کانال بله, جهت پشتیبانی و اطلاع رسانی کانال بله, جهت پشتیبانی و اطلاع رسانی
عضویت

آموزش استفاده از کتابخانه ی Otto event bus در پروژه های اندرویدی

نصب کتابخانه

استفاده از این کتابخانه در جاوا یا اندروید بسیار ساده است، کافی است فایل JAR و تنها نیازمندی آن را از http://square.github.io/otto/ دانلود کرده و سپس آن را به متغیر classpath اپلیکیشن اضافه نمایید.

در صورت استفاده از Maven یا Gradle به عنوان سیستم کامپایل و build پروژه، شما می توانید به راحتی کتابخانه مورد نیاز (dependency) را به شناسه ی گروه (Group ID) com.squareup، شناسه ی artifact (otto) و ورژن 1.3.5 اضافه نمایید.

چه زمانی باید از Otto استفاده کرد؟

Otto ابزار خوبی برای مهیا کردن امکان ارتباط بین activity و fragment های زیرمجموعه ی آن و یا تبادل داده بین activity و service می باشد.

چگونگی تنظیم Otto

توجه:

آموزش حاضر فرض را بر این می گذارد که توسعه دهنده کتابخانه ی Otto را در یک اپلیکیشن اندرویدی مورد استفاده قرار می دهد، اگرچه امکان استفاده از آن در بستر پروژه های جاوایی نیز وجود دارد.

جهت استفاده از Otto، لازم است یک نمونه ی واحد (singleton instance) از کلاس Bus ایجاد کرده و سپس برای کامپوننت های نرم افزاری اندروید امکان دسترسی به آن را فراهم نمایید. عملیات مزبور در آبجکت Application پروژه ی اندرویدی شما انجام می شود.

public static Bus bus = new Bus(ThreadEnforcer.MAIN);

در مثال جاری، همان طور که مشاهده می کنید، مقدار ThreadEnforcer.MAIN به عنوان پارامتر به تابع سازنده ی کلاس Bus ارسال شده است. به واسطه ی این پارامتر، Otto، به سیستم اعلان می کند که event ها منحصرا باید از thread اصلی ارسال شوند. اگر مهم نیست که رخداد از کدام thread ارسال می شود، پارامتر ThreadEnforcer.ANY به عنوان آرگومان به تابع سازنده ی Bus پاس داده می شود.

نحوه ی registerیا گوش دادن به event ها و unregister آن ها

جهت گوش دادن به رخدادها (event registration)، لازم است دستور @Subscribe را در بالای متد که با سطح دسترسی public تعریف شده و فقط یک پارامتر ورودی دارد، درج نمایید. پارامتر ارسالی به متد در واقع event key محسوب می شود، بدین معنی که چنانچه چنین نوع داده ای (data type) به واسطه ی event bus (واسط و مدیریت کننده ی رخدادها Otto) ارسال شود، در آن صورت متد مرتبط صدا زده می شود.

event receiver ها (متدهایی که رخداد را دریافت می کنند) بایستی خود را به وسیله ی تابع register از کلاس Bus ثبت کرده و به رخداد مربوطه گوش فرا دهند.

// subscribe for string messages
@Subscribe
public void getMessage(String s) {
        Toast.makeText(this, s, Toast.LENGTH_LONG).show();
}
//subscribe for TestData messages
@Subscribe
public void getMessage(TestData data) {
        Toast.makeText(getActivity(), data.message, Toast.LENGTH_LONG).show();
}
//requires a registration e.g. in the onCreate method
bus.register(this);

جهت unregister کردن و قطع فرایند گوش دادن به event ها، کافی است متد unregister() را فراخوانی نمایید.

نحوه ی ارسال event ها

برای ارسال رخداد نیازی به register در event bus نیست. کافی است متد post() از کلاس Bus را فراخوانی نمایید (متد post را بر روی آبجکت ساخته شده از کلاس Bus صدا بزنید).

// post a string object
bus.post("Hello");
// example data to post
public class TestData {
        public String message;
}
// post this data
bus.post(new TestData().message="Hello from the activity");

چگونه کامپوننت های نرم افزاری جدید می توانند آخرین event را دریافت کنند؟

در صورتی که کامپوننت های جدید، نظیر یک fragment که به صورت dynamic و در زمان اجرا ایجاد شده، داده های مربوط به event را در طول فرایند ایجاد دریافت کنند، کامپوننت های نرم افزاری می توانند از طریق دستور @Produce خود را به عنوان producer یا تولید کننده ی داده های رخداد معرفی (register) کنند.

event receiver ها (کامپوننت هایی که می خواهند به event گوش داده و قرار است داده های مربوط به رخداد را دریافت کنند) بایستی متد register را از کلاس Bus فراخوانی نمایند.

@Produce
public String produceEvent() {
        return "Starting up";
}
تمرین :

استفاده ی کاربردی از کتابخانه ی Otto event bus

مثال حاضر کتابخانه ی Otto را به صورت کاربردی در یک پروژه ی اندرویدی مورد استفاده قرار می دهد. هرچند این کتابخانه در اپلیکیشن های جاوا نیز قابل فراخوانی و استفاده می باشد.

یک پروژه ی اندرویدی به نام com.vogella.java.library.otto، بر اساس قالب آماده ی (template) Empty Activity with Fragment ایجاد نمایید.

چنانچه برای برنامه نویسی از محیط کاری Eclipse استفاده می کنید، در آن صورت فایل Otto JAR را دانلود کرده و سپس آن را به build path پروژه ی خود اضافه نمایید.

در صورت استفاده از Gradle، کافی است کتابخانه (dependency) مورد نیاز را به فایل build.gradle اضافه نمایید.

apply plugin: 'com.android.application'
android {
    compileSdkVersion 22
    buildToolsVersion "21.1.2"
    defaultConfig {
        applicationId "com.example.android.rssreader"
        minSdkVersion 22
        targetSdkVersion 22
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}
dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    compile project(':com.example.android.rssfeedlibrary')
    compile 'com.squareup:otto:1.3.5'
    compile 'org.achartengine:achartengine:1.2.0'
}

محتوای فایل تنظیم ظاهر اپلیکیشن، activity_main.xml layout، بایستی ظاهری مشابه زیر داشته باشد.


فایل تنظیم کننده ی ظاهر fragment، fragment_main.xml، بایستی محتوای مشابه زیر داشته باشد.




پس از تعریف کردن fragment، آن را به صورت dynamic و داخل کلاس جاوایی به activity اضافه نمایید. سپس یک رخداد به ترتیب از fragment به activity و بالعکس ارسال کنید. در هر دو سناریو پس از دریافت رخداد یک پیغام Toast برای کاربر به نمایش بگذارید.

package com.vogella.android.otto;
import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import com.squareup.otto.Bus;
import com.squareup.otto.Produce;
import com.squareup.otto.Subscribe;
import com.squareup.otto.ThreadEnforcer;
import library.java.vogella.com.otto.R;
public class MainActivity extends Activity {
    public static Bus bus;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if (savedInstanceState == null) {
            getFragmentManager().beginTransaction().add(R.id.container, new PlaceholderFragment()).commit();
        }
        bus = new Bus(ThreadEnforcer.MAIN);
        bus.register(this);
    }
    @Subscribe
    public void getMessage(String s) {
        Toast.makeText(this, s, Toast.LENGTH_LONG).show();
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            TestData t = new TestData();
            t.message="Hello from the activity";
            bus.post(t);
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
    public class TestData {
        public String message;
    }
    /**
     * A placeholder fragment containing a simple view.
     */
    public static class PlaceholderFragment extends Fragment {
        public PlaceholderFragment() {
        }
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.fragment_main, container, false);
            View button = rootView.findViewById(R.id.fragmentbutton);
            button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    bus.post("Hello from the Fragment");
                }
            });
            bus.register(this);
            return rootView;
        }
        @Subscribe
        public void getMessage(MainActivity.TestData data) {
            Toast.makeText(getActivity(), data.message, Toast.LENGTH_LONG).show();
        }
    }
    @Produce
    public String produceEvent() {
        return "Starting up";
    }
}
توجه:

مثال حاضر به طور عمد این گونه ساده طراحی شده است. در یک اپلیکیشن واقعی و تمام عیار اندروید، توسعه دهنده یک نمونه ی واحد (singleton) از کلاس Bus در آبجکت Application ایجاد کرده و fragment را داخل فایل مجزای خود قرار می دهد.

1396/03/21 3456 0
نظرات شما

نظرات خود را ثبت کنید...