EventBus 3.0---真之我见

来源:互联网 发布:网络简介的阅读答案 编辑:程序博客网 时间:2024/04/30 21:33

前言

EventBus是一款针对Android优化的发布/订阅事件总线。主要功能是替代Intent,Handler,BroadCast在Fragment,Activity,Service,线程之间传递消息.优点是开销小,代码更优雅。以及将发送者和接收者解耦。但缺点是大量的滥用,将导致逻辑的分散,出现问题后很难定位。

如何使用?(AS背景)

(1)module下添加EventBus3.0的依赖

compile 'org.greenrobot:eventbus:3.0.0'

(2)在要订阅消息的页面注册

EventBus.getDefault().register(this);

(3)定义接受事件的方法,指定线程接收模式

//注意:参数不支持基本数据类型,整型必须使用Integer,支持自定义模型@Subscribe(threadMode = ThreadMode.MAIN)public void onHandMessage(String msg){    message.setText(msg);}

(4)发送事件

EventBus.getDefault().post("post message");

(3)在结束的时候解绑事件

EventBus.getDefault().unregister(this);

至此使用完毕,但是以下几点需要注意
1.上述步骤三中的定义接收事件,接收模式说明

(1).POSTING:同步模式,顾名思义只中方式就是接收事件方法的线程和发送事件方法的线程一致,如果发送事件是在主线程中,那么接收事件也是在主线程中。如果发送事件的是在子线程,那么那么接收事件也会发送事件的子线程执行。总之会保持一致。

(2).MAIN:主线程模式,无论发送事件是在那个线程发送,接收事件一定会在主线程中执行。这样刚好就解决了只能在主线程中更新UI的问题。

(3).BACKGROUND:后台线程模式,如果发送事件的是在主线程中发送,接收事件就会在新建一个子线程中执行。发送事件是在子线程中执行,接收事件就会发发送事件的子线程中执行。这种模式适合处理耗时任务。

(4).ASYNC:新线程模式,无论发送事件是在何种线程执行,接收事件一定会新建一个子线程去接收。

示例:

@Subscribe(threadMode = ThreadMode.MAIN)public void onHandMain(String message){    Log.v("main",Thread.currentThread().getName());}@Subscribe(threadMode = ThreadMode.POSTING)public void onHandPosting(String message){    Log.v("posting",Thread.currentThread().getName());}@Subscribe(threadMode = ThreadMode.BACKGROUND)public void onHandBackground(String message){    Log.v("background",Thread.currentThread().getName());}@Subscribe(threadMode = ThreadMode.ASYNC)public void onHandAsync(String message){    Log.v("async",Thread.currentThread().getName());}

在主线程和工作线程中分别发送消息

public void sendOnMainThread(){    EventBus.getDefault().post("sendOnMainThread");}public void SendOnWorkThread(){    new Thread(new Runnable() {        @Override        public void run() {                 EventBus.getDefault().post("SendOnWorkThread");        }    }).start();}

点击主线程发送结果

mainmainpool-1-thread-2pool-1-thread-1

点击工作线程发送结果

mainThread-115Thread-115pool-1-thread-1

因此验证上面的结论。

优先级

EventBus可以通过设置每个接收事件方法的优先级@Subscribe(priority = 1)开控制接收方法的先后,实例代码:

@Subscribe(threadMode = ThreadMode.MAIN,priority = 1)public void onHandMain(String msg){    Log.v("onHandMain",msg+1);}

priority的值越大,接收顺序就越靠前。如果指定俩个方法的priority的值为1和2,那么priority为2的先接收到,为1的后接收到,还可以在方法内通过cancelEventDelivery()截断事件的传递。

public class testPriorityActivity extends Activity{    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        this.setContentView(R.layout.activity_priority);        EventBus.getDefault().register(this);    }    @Override    protected void onDestroy() {        super.onDestroy();        EventBus.getDefault().unregister(this);    }    @Subscribe(threadMode = ThreadMode.MAIN,priority = 0)    public void onEvent(String msg){        Log.v("onEvent",0 + msg);    }    @Subscribe(threadMode = ThreadMode.MAIN,priority = 1)    public void onEvent1(String msg){        Log.v("onEvent",1 + msg);    }    @Subscribe(threadMode = ThreadMode.POSTING,priority = 2)    public void onEvent2(String msg){        Log.v("onEvent",2 + msg);    }    @Subscribe(threadMode = ThreadMode.MAIN,priority = 3)    public void onEvent3(String msg){        Log.v("onEvent",3 + msg);    }    public void click(View view){        EventBus.getDefault().post("发送消息");    }}

没有加取消事件的logcat结果:

3发送消息2发送消息1发送消息0发送消息

加上取消事件传递:

@Subscribe(threadMode = ThreadMode.POSTING,priority =3)public void onEvent(String msg){    Log.v("onEvent",3+ msg);    EventBus.getDefault().cancelEventDelivery(msg);}

logcat结果

3发送消息

1,2,3优先级无法收到消息。

tips:在取消事件传递的方法的线程Mode必须是POSTING的,不然会报event handlers may only abort the incoming event的异常.

黏性事件

EventBus支持粘性事件,粘性事件就是在发送了事件之后,再订阅事件,而不是在发送事件之前订阅,事件接收方法也能收到,通过@Subscribe(sticky = true)去指定,发送事件必须通过postSticky发送。修改如下:

EventBus.getDefault().postSticky("粘性消息");EventBus.getDefault().register(this);

混淆配置

-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);}

ok,大功告成.

参考链接:

EventBus 3.0混淆官网

0 0
原创粉丝点击