1. 程式人生 > >Otto事件匯流排框架的使用

Otto事件匯流排框架的使用

Otto是一個在Android中的事件匯流排框架,它是square公司的一個開源框架。

為什麼要使用Otto事件匯流排:

通常來說在Android中:

1、Activity與Activity間的傳值是通過Intent,值回撥是通過startActivityForResult()

2、Activity與Fragment間的傳值是通過setArguments,值回撥是通過實現onAttach()的Interface方式

3、而Fragment與Fragment間的互動則應該是通過它們關聯的Activity作為中間鍵來互動

4、包括Activity與Service的互動,可能眾多同學會採用Binder機制來處理,而其實Binder機制本質也是通過介面回撥方式來進行值回撥的

5、在更復雜的應用場景下,比如:Activity A跳轉到Activity B,Activity B 跳轉到Activity C,此時需要從Activity C中獲取到使用者的操作資料返回到Activity A 和ActivityB中顯示,或者在Activity中有多個Fragment,其中一個Fragment裡的資料變化需要同步更新其他Fragment的資料變化,這時候如果使用Interface的方式進行它們間的互動則比較複雜,耦合度也高。

所以,針對上面這些問題,大多數在處理值互動的問題上類之間都是耦合在一起的,而Otto事件匯流排框架就是降低各個類間的耦合度的。

Otto事件匯流排

Otto中真正用到的就只有一個類兩個註解三個方法:

1、Bus-管理註冊、登出和釋出事件

2、@Produce-標記該方法是生產者,產生的事件內容為該方法的返回值

3、@Subscribe-標記該方法是訂閱者,表示訂閱了一個事件,方法需要修飾符為public,而區分不同的訂閱者是通過方法的引數來區分的,且訂閱了某事件的所有訂閱者都可以收到該事件。

4、register(Object obj)-註冊,訂閱事件前都需要註冊

5、unregister(Object obj)-登出,放棄之前所有事件的訂閱

6、post(Object event)-釋出一個事件,這個事件會被所有標記了@Subscribe註解的方法獲得

使用事件匯流排

首先新增依賴

dependencies{
    compile 'com.squareup:otto:+'
}

1、為了避免重複建立Bus物件,我們先為Bus建立一個單例物件

public class BusProvider{
    private volitile static Bus bus=null;
    
    private BusProvider(){
    }

    public static Bus getInstance(){
        if(bus==null){
            synchronized(BusProvider.class){
                bus=new Bus();
                }
            }
            return bus;
        }
    }

2、建立一個Bean,用來傳遞各類間的資料

public class EventData{
    private String content;
    
    public String getContent(){
        return content;
    }

    public void setContent(String content){
        this.content=content;
    }
}

3、在MainActivity中註冊並且建立訂閱者訂閱資料

public class MainActivity extends AppCompatActivity{
    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate();
        setContentView(R.layout.activity_main);
        
        BusProvider.getInstance().register(this);//訂閱事件
        
        Button mButton=(Button)findViewById(R.id.btn);
        mButton.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v){
                TestActivity.jumpToTestActivity(MainActivity.this);
             }
            
            });
        }

        @Subscribe
        public void subscribeEvent(EventData data){
            Log.v("zxy",data.getContent());
        }

        @Override
        protected void onDestroy(){
            super.onDestroy();
            BusProvider.getInstance().unregister(this);//登出訂閱
        }

        public static void jumpToMainActivity(Context context){
             context.startActivity(new Intent(context,MainActivity.class));
         }
    }
        

4、在TestActivity中釋出事件

釋出事件有兩種方法:

1.使用@Produce註解來產生事件,不過它生產事件前需要註冊、生產完事件後需要登出,如果使用這種方法則在跳轉到生產者所在的類中則會立即產生事件觸發訂閱者,即在MainActivity跳轉到TestActivity時,會立即產生事件並訂閱了該事件的方法會收到該事件,如:

public class TestActivity extends AppCompatActivity{
       
    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);

        BusProvider.getInstance().register(this);
    }
    
    @Produce
    public EventData produceEvent(){
        EventData mEventData=new EventData();
        mEventData.setContent("hello world!");
        return mEventData;
    }

    @Override
    protected void onDestroy(){
        super.onDestroy();
        BusProvider.getInstance().unregister(this);
    }

    
    public static void jumpToTestActivity(Context context){
        context.startActivity(new Intent(context,TestActivity.class));
    }
}

則在MainActivity跳轉到TestActivity時訂閱者會馬上收到事件,輸出的Log資訊為:

09-06 03:46:16.738 5958-5958/? V/zxy﹕ hello word!

2、通過post()來發布事件,它不需要註冊和登出,而且它不會在介面跳轉時馬上釋出事件,而是我們人為的控制該事件什麼時候釋出,使用如下

public class TestActivity extends AppCpmpatActivity{
    
    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
    }

    public void click(View view){
        EventData mEventData=new EventData();
        BusProvider.getInstance().post(mEventData);//釋出事件
        
        MainActivity.jumpToMainActivity(this);
    }

    public static void jumpToTestActivity(Context context){
        context.startActivity(new Intent(context,TestActivity.class));
    }
}

當我們點選按鈕的時候,這個事件就釋出出去了,而訂閱了該事件的方法就會收到,列印的Log為:

09-06 03:46:18.738 5958-5958/? V/zxy﹕ hello word!