EventBus3.0帶你樂翻天

來源:互聯網
上載者:User

EventBus3.0帶你樂翻天

你還在為重新整理ui傷透腦筋嗎?你還在琢磨如何使用介面回調或者handle來實現嗎?如果你想到了使用觀察者模式,那麼一個很屌的Android開源架構EventBus:主要功能是替代Intent、Handler、BroadCast在Fragment、Activity、Service、線程之間傳遞訊息。他的最牛逼優點是開銷小,代碼簡潔,解耦代碼。

如果你沒有使用過eventBus那麼很遺憾你錯過了很多,不過沒有關係3.0的正式發布,使用沒有什麼大不一樣只是效能更好。個人建議直接使用3.0.0的版本,也不要去使用2.4和3.0beta1的版本了

看圖說話:
EventBus是一款針對Android最佳化的發布/訂閱(publish/subscribe)事件匯流排。

EventBus作為一個訊息匯流排,有三個主要的元素:

Event:事件。可以是任意類型的對象 Subscriber:事件訂閱者,接收特定的事件。在EventBus中,使用約定來指定事件訂閱者以簡化使用。即所有事件訂閱都都是以onEvent開頭的函數,具體來說,函數的名字是onEvent,onEventMainThread,onEventBackgroundThread,onEventAsync這四個,這個和
ThreadMode(下面講)有關。 Publisher:事件發行者,用於通知 Subscriber 有事件發生。可以在任意線程任意位置發送事件,直接調用eventBus.post(Object) 方法,可以自己執行個體化 EventBus
對象,但一般使用預設的單例就好了:EventBus.getDefault(), 根據post函數參數的類型,會自動調用訂閱相應類型事件的函數。
EventBus使用詳解EventBus使用步驟(1)引入EventBus:

引入eventbus:2.4.0(回顧老版本)

compile ‘de.greenrobot:eventbus:2.4.0’

引入eventbus:3.0.0-beta1

compile ‘de.greenrobot:eventbus:3.0.0-beta1’

引入eventbus:3.0.0

compile ‘org.greenrobot:eventbus:3.0.0’

(2)定義一個訊息類,該類可以不繼承任何基類也不需要實現任何介面。如:
public class MessageEvent {    ......}
(3)在需要訂閱事件的地方註冊事件

EventBus.getDefault().register(this);

(4)發送事件:即發送訊息

EventBus.getDefault().post(messageEvent);

(5)處理訊息

在3.0之前,EventBus還沒有使用註解方式。訊息處理的方法也只能限定於onEvent、onEventMainThread、onEventBackgroundThread和onEventAsync,分別代表四種執行緒模式。而在3.0之後,訊息處理的方法可以隨便取名,但是需要添加一個註解@Subscribe,並且要指定執行緒模式(beta1預設為PostThread,正式版預設為POSTING),四種執行緒模式,下面會講到。
注意,事件處理函數的存取權限必須為public,否則會報異常。

EventBus3.0與EventBus2.4的區別EventBus 2.4在使用方式
 public void onEvent(MessageEvent event) {// 事件在哪個線程發布出來的,onEvent就會在這個線程中運行,也就是說發布事件和接收事件線程在同一個線程。使用這個方法時,在onEvent方法中不能執行耗時操作,如果執行耗時操作容易導致事件分發延遲。    }
 public void onEventMainThread(MessageEvent event) {// 不論事件是在哪個線程中發布出來的,onEventMainThread都會在UI線程中執行,接收事件就會在UI線程中運行,這個在Android中是非常有用的,因為在Android中只能在UI線程中跟新UI,所以在onEvnetMainThread方法中是不能執行耗時操作的。    }
public void onEventBackgroundThread(MessageEvent event){//那麼如果事件是在UI線程中發布出來的,那麼onEventBackground就會在子線程中運行,如果事件本來就是子線程中發布出來的,那麼onEventBackground函數直接在該子線程中執行。    }
public void onEventAsync(MessageEvent event){//使用這個函數作為訂閱函數,那麼無論事件在哪個線程發布,都會建立新的子線程在執行onEventAsync.    }
在EventBus 3.0.0的使用是這樣的
(1) beta1版的寫法
  @Subscribe(threadMode = ThreadMode.PostThread) //3.0.0-beta1    public void onMessageEventPost(UserEvent event) {    //預設, 在發送線程執行    }
 @Subscribe(threadMode = ThreadMode.MainThread)     public void onMessageEventMain(UserEvent event) {    //在ui線程執行    }
   @Subscribe(threadMode = ThreadMode.BackgroundThread)    public void onMessageEventBackground(UserEvent event) {     //在後台線程執行    }
 @Subscribe(threadMode = ThreadMode.Async)     public void onMessageEventAsync(UserEvent event) {    //強制在後台執行    }

(2) 正式版的寫法

  @Subscribe(threadMode = ThreadMode.POSTING) //3.0.0    public void onMessageEventPost(UserEvent event) {    //預設, 在發送線程執行    }
 @Subscribe(threadMode = ThreadMode.MAIN)     public void onMessageEventMain(UserEvent event) {    //在ui線程執行    }
   @Subscribe(threadMode = ThreadMode.BACKGROUND)    public void onMessageEventBackground(UserEvent event) {     //在後台線程執行    }
 @Subscribe(threadMode = ThreadMode.ASYNC)     public void onMessageEventAsync(UserEvent event) {    //強制在後台執行    }
(6)取消訊息訂閱

EventBus.getDefault().unregister(this);

(7)代碼混淆
#EventBus -keepclassmembers class ** {    public void onEvent*(**);    void onEvent*(**); }

看下簡單實現的效果:

看下具體的代碼使用:

package com.losileeya.eventbusapp;import android.content.Intent;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.TextView;import android.widget.Toast;import com.losileeya.eventbusapp.event.EventBusEvents;import org.greenrobot.eventbus.EventBus;import org.greenrobot.eventbus.Subscribe;import org.greenrobot.eventbus.ThreadMode;public class MainActivity extends AppCompatActivity implements View.OnClickListener {    private Button btn_first,btn_second,btn_third;    private TextView tv_toast;    private TextView tv_default,tv_main,tv_background,tv_asy;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        EventBus.getDefault().register(this);        btn_first = (Button) findViewById(R.id.btn_first);        btn_second = (Button) findViewById(R.id.btn_second);        btn_third = (Button) findViewById(R.id.btn_third);        tv_toast= (TextView) findViewById(R.id.tv_toast);        tv_default= (TextView) findViewById(R.id.tv_default);        tv_main= (TextView) findViewById(R.id.tv_main);        tv_background= (TextView) findViewById(R.id.tv_background);        tv_asy= (TextView) findViewById(R.id.tv_asy);        btn_first.setOnClickListener(this);        btn_second.setOnClickListener(this);        btn_third.setOnClickListener(this);    }    @Override    public void onClick(View v) {        Intent intent;        switch (v.getId()){            case R.id.btn_first:                intent = new Intent(MainActivity.this,FirstActivity.class);                startActivity(intent);                break;            case R.id.btn_second:                intent = new Intent(MainActivity.this,SecondActivity.class);                startActivity(intent);                break;            case R.id.btn_third:                intent = new Intent(MainActivity.this,ThirdActivity.class);                startActivity(intent);                break;        }    }    @Subscribe(threadMode = ThreadMode.MAIN)    public void onMessageMain(EventBusEvents.FirstEvent firstEvent){        tv_toast.setText(firstEvent.getValue());        Toast.makeText(this, firstEvent.getValue(),Toast.LENGTH_SHORT).show();        Log.d("zy", "onEventMainThread-->"+Thread.currentThread().getId());        tv_main.setText(Thread.currentThread().getId()+"");    }    /**     * 使用onEvent來接收事件,那麼接收事件和分發事件在一個線程中執行     * @param event     */    @Subscribe(threadMode = ThreadMode.POSTING)    public void onPost(EventBusEvents.FirstEvent firstEvent)    {        Log.d("zy", "onEventPost-->"+Thread.currentThread().getId());        tv_default.setText(Thread.currentThread().getId()+"");    }    /**     * 使用onEventBackgroundThread來接收事件,如果分發事件在子線程運行,那麼接收事件直接在同樣線程     * 運行,如果分發事件在UI線程,那麼會啟動一個子線程運行接收事件     * @param event     */    @Subscribe(threadMode = ThreadMode.BACKGROUND)    public void onBackgroundThread(EventBusEvents.FirstEvent firstEvent)    {        Log.d("zy", "onEventBackgroundThread-->"+Thread.currentThread().getId());        tv_background.setText(Thread.currentThread().getId()+"");    }    /**     * 使用onEventAsync接收事件,無論分發事件在(UI或者子線程)哪個線程執行,接收都會在另外一個子線程執行     * @param event     */    @Subscribe(threadMode = ThreadMode.ASYNC)    public void onAsync(EventBusEvents.FirstEvent firstEvent)    {        Log.d("zy", "onEventAsync-->"+Thread.currentThread().getId());        tv_asy.setText(Thread.currentThread().getId()+"");    }    @Override    protected void onDestroy() {        super.onDestroy();        EventBus.getDefault().unregister(this);    }}
package com.losileeya.eventbusapp;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.view.View;import android.widget.Button;import com.losileeya.eventbusapp.event.EventBusEvents;import org.greenrobot.eventbus.EventBus;public class FirstActivity extends AppCompatActivity {    private Button btn_showDownLoad;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_first);        btn_showDownLoad = (Button) findViewById(R.id.btn_toast);        btn_showDownLoad.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                new Thread(new Runnable() {                    @Override                    public void run() {                        try {                            Thread.sleep(1000);                        } catch (InterruptedException e) {                            e.printStackTrace();                        }                        EventBus.getDefault().post(new EventBusEvents.FirstEvent("我是從網路下載的文本"));                    }                }).start();            }        });    }}

可以看出哪裡需要發送訊息,那麼就必須使用:

EventBus.getDefault().post(your event)

然後你只需要訂閱就好了:

   @Subscribe(threadMode = ThreadMode.MAIN)    public void onMessageMain(EventBusEvents.FirstEvent firstEvent){        tv_toast.setText(firstEvent.getValue());        Toast.makeText(this, firstEvent.getValue(),Toast.LENGTH_SHORT).show();    }
  

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.