EventBus 3.0使用詳解源碼分析(一)

目錄

 

 Eventbus前言

 EventBus簡介

 EventBus使用


  •  Eventbus前言

        在項目開發中,總會遇到組件和組件之間,組件和線程、service之間進行通信,比如activity和多個fragment通信。android 原生也提供了一下方法,我們經常用的,有廣播,handler,寫回調方法以及intent。這些都可以解決通信需求,但是這樣耦合度比較高,並且代碼量也比較大。今天介紹的eventbus可以很方便的解決這些問題。

  •  EventBus簡介

         首先容許我盜一張圖:

          大致意思是說,eventbus能夠簡化組件間通信,代碼更簡單,有效分離了時間發送方和接收方,並且有很多應用集成了eventbus安全和性能應該有保障。但是eventbus也有一個不太便利的地方。如果事件種類比較多的情況。那麼觀察者需要註冊的函數就會變得很多。這樣就會帶來一些不便,再有就是後來者接手項目,不熟悉代碼的情況下,比較難找到他的來龍去脈。

           最後單獨說一下他的基本原理: eventbus就是一個典型的觀察者模式的使用,通過publisher發佈消息,然後Subscriber接收消息。然後進行處理。整個結構大致有三個模塊需要注意:

  •             1 event:發佈者發佈的消息,可以是繼承自Object的任意類。
  •             2 publisher:事件的發佈者,可以在任意線程發佈消息,一般通過EventBus.getDefault().post(Event)就可以發佈。
  •             3 Subscriber:  事件的接收者,通過register,unregister函數來註冊成爲觀察者。處理事件的方法要通過註解@Subscribe()中的參數來標明處理事件的線程模型,優先權,以及是否是黏性廣播。

           在觀察者類中處理消息的函數要通過註解@Subscribe(ThreadMode,isSticky,priority)來指定處理消息的一些基本信息,註解共有三個參數。其中ThreadMode表示在哪個線程裏面處理收到的消息,它有四種方式:     

  •              1 POSTING, 默認參數,哪個線程發佈的消息,就在哪個線程裏面處理消息。
  •              2 MAIN, 表示在主線程處理消息,就是ui線程,不能進行耗時操作。
  •             3 BACKGROUND, 表示後臺線程處理,不能進行ui操作,如果發佈消息在ui線程中發佈,那會重啓一個線程,如果是後臺線程,就在發佈消息的線程處理。
  •             4 ASYNC ,無論發佈線程是哪個,都會重新開一個線程處理。可以進行耗時操作。

             sticky 這個參數表示是否是黏性廣播,默認false,非黏性廣播當發佈者發佈消息的時候,沒有註冊的開發者不能收到任何消息,如果註冊爲黏性,那麼當觀察者註冊成功之後,會收到最後一條發佈的廣播。

             priority表示處理的優先級。默認爲0.

  •  EventBus使用

         首先添加依賴:

implementation 'org.greenrobot:eventbus:3.1.1'

         如果需要混淆要添加一下代碼:

         

-keepattributes *Annotation*
-keepclassmembers class * {
    @org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }
 
# Only required if you use AsyncExecutor
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
    <init>(java.lang.Throwable);
}

       簡單寫一個消息類:

public class MessageEvent extends MessageObject{

    String message;

    int id;

    public MessageEvent(String msg,int id){
        super(msg);
        this.message = msg;
        this.id = id;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
}

  eventbus可以用於activity,fragment,service等控件,其註冊方式都一樣,本文用activity做例子,發送消息的activity如下:

public class MainActivity extends Activity {

    @BindView(R.id.mainclick)
    Button mainClick;

    @BindView(R.id.threadclick)
    Button threadClick;

    WidgetBroadcastReceiver mReceiver;

    RxPermissions rxPermissions;

    @SuppressLint("HandlerLeak")
    Handler mHandler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 1:
                    postMsgMain();
                    postMsgThread();
                    break;
                default:
                    break;
            }
        }
    };


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mReceiver = new WidgetBroadcastReceiver();
        ButterKnife.bind(this);
        mainClick.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent ii = new Intent(MainActivity.this, EventBusActivity.class);
                startActivity(ii);
                mHandler.sendEmptyMessageDelayed(1, 1000 * 5);

            }
        });

    }

    private void postMsgMain(){
        EventBus.getDefault().post(new MessageObject("this is default"));
        Log.e("tag"," ****main id===="+Thread.currentThread().getId());
    }

    private void postMsgThread() {
       new Thread(new Runnable() {
            @Override
            public void run() {
                EventBus.getDefault().post(new MessageEvent("from thread",1 ));
                Log.e("tag","*thread id===="+Thread.currentThread().getId());
            }
        }).start();

    }

}

點擊按鈕延後5,6秒通過EventBus.getDefault().post()分別發送一個主線程消息和後臺消息。

public class EventBusActivity extends Activity {

    @BindView(R.id.content_text)
    TextView contentView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_event_bus);
        ButterKnife.bind(this);
        //註冊觀察者
        EventBus.getDefault().register(this);
    }


    /**
     * 處理消息,只能是一個參數,通過參數識別處理哪個消息。發送的消息和參數匹配纔會處理。
     * @param me
     */
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(MessageObject me) {
        String content = me.getObject();
        contentView.setText(content);
        Log.e("tag", "the MAIN msg id==="+Thread.currentThread().getId());
    }

    @Subscribe(threadMode = ThreadMode.POSTING)
    public void onMessageEvent1(MessageEvent me) {
        String content = me.getMessage();
        Log.e("tag", "the POSTING msg===" + me.getMessage()+Thread.currentThread().getId());
    }

    @Subscribe(threadMode = ThreadMode.BACKGROUND)
    public void onMessageEvent2(MessageEvent me) {
        String content = me.getMessage();
        Log.e("tag", "the BACKGROUND msg===" + me.getMessage()+Thread.currentThread().getId());
    }
    
    @Subscribe(threadMode = ThreadMode.ASYNC)
    public void onMessageEvent3(MessageEvent me) {
        String content = me.getMessage();
        Log.e("tag", "the ASYNC msg===" + me.getMessage()+Thread.currentThread().getId());
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if(EventBus.getDefault().isRegistered(this)) {
            //取消註冊
            EventBus.getDefault().unregister(this);
        }
    }
}

在這裏接收處理消息。在這個例子中通過打印線程id確認執行屬性。日誌如下:

 

 EventBus的基本用法就是這樣,接下來我會分析源碼來解釋eventbus的運行機制。

EventBus 3.0 使用詳解源碼分析(二)

 EventBus的github地址:

 eventbus源碼

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章