EventBus3.0使用介绍

来源:互联网 发布:excel 设置数据有效性 编辑:程序博客网 时间:2024/06/02 05:29

EventBus3.0使用介绍

前言:之前组件间通信一直用动态广播的方式。主要是点赞状态的更新。
不太喜欢接口回调,因为有点繁琐,逻辑上不好理解和维护。所以简答的需求,基本上广播就可以满足了,当然广播还有一些高级功能,静态注册、普通广播、有序广播、粘性广播(滞留广播)、本地广播、广播的优先级、广播分发拦截。一般本地广播就可以实现应用内部组件间的通信。本地广播和其他两个广播的区别是:本地广播只在本应用中生效。普通广播和无序广播作用全局。

  • 动态广播:广播的方式,很好理解和维护。但是代码量稍微有点多。

    发送广播:

    Intent intent = new Intent();intent.setAction("updatePostCommoList");//标识广播intent.putExtra("childBean",childBean);//携带数据LocalBroadcastManager.getInstance(this)        .sendBroadcast(intent);//获取广播单例。进行发送广播

    接受广播:

    LocalBroadcastManager localBroadcastManager = LocalBroadcastManager        .getInstance(getActivity());IntentFilter intentFilter = new IntentFilter();intentFilter.addAction("updateFragment");intentFilter.addAction("updateUserAllMessage");BroadcastReceiver br = new BroadcastReceiver() {    @Override    public void onReceive(Context context, Intent intent) {        if (intent.getAction().equals("updateFragment")) {           //根据不同标识,doSomething        }    }};localBroadcastManager.registerReceiver(br, intentFilter);
  • EventBus3.0 :稍微比广播代码量少点,但是得引入第三方库(50k)。现在这个代码量爆炸得年代,50k还能接受

使用方式

  1. 在需要订阅得地方,进行注册,解除注册

    @Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    EventBus.getDefault().register(this);}@Overrideprotected void onDestroy() {    super.onDestroy();    EventBus.getDefault().unregister(this);}
  2. 事件订阅

     @Subscribe(threadMode = ThreadMode.POSTING) public void helloEventBus(Person message){            Log.e("weiwei", "POSTING_helloEventBus: "+Thread.currentThread().getName() );     mTextView.setText(message.getName()); }
  3. 发送事件

     EventBus.getDefault().post(person);

ThreadMode有四种模式:

  • ThreadMode.POSTING:如果使用POSTING作为订阅注解参数,那么该事件在哪个线程发布出来的,helloEventBus就会在这个线程中运行,也就是说发布事件和接收事件线程在同一个线程。使用这个方法时,在helloEventBus方法中不能执行耗时操作,如果执行耗时操作容易导致事件分发延迟。
  • ThreadMode.MAIN:如果使用MAIN作为订阅注解参数,那么不论事件是在哪个线程中发布出来的,helloEventBus都会在UI线程中执行,接收事件就会在UI线程中运行,这个在Android中是非常有用的,因为在android中只能在UI线程中跟新UI,所以在helloEventBus方法中是不能执行耗时操作的。
  • ThreadMode.BACKGROUND:如果使用BACKGROUND作为注解参数,那么如果事件是在UI线程中发布出来的,那么helloEventBus就会在子线程中运行,如果事件本来就是子线程中发布出来的,那么helloEventBus函数直接在该子线程中执行。
  • ThreadMode.ASYNC:使用ASYNC作为订阅注解参数,那么无论事件在哪个线程发布,都会创建新的子线程在执行helloEventBus。

使用进阶

上面的基本使用方式,基本上可以满足大部分需要。EventBus还有更高级的功能,实现复杂的逻辑。基本上和广播一样,事件的优先级、事件拦截。

订阅事件的优先级

 @Subscribe(threadMode = ThreadMode.POSTING,priority = 100)public void helloEventBus(Person message){    Log.e("weiwei", "POSTING_helloEventBus: "+Thread.currentThread().getName() );    mTextView.setText(message.getName());}@Subscribe(threadMode = ThreadMode.MAIN,priority = 101)public void hello1EventBus(Person message){    Log.e("weiwei", "MAIN_helloEventBus: "+Thread.currentThread().getName() );    mTextView1.setText(message.getName());}@Subscribe(threadMode = ThreadMode.BACKGROUND,priority = 102)public void hello2EventBus(Person message){    Log.e("weiwei", "BACKGROUND_helloEventBus: "+Thread.currentThread().getName() );    mTextView2.setText(message.getName());}@Subscribe(threadMode = ThreadMode.ASYNC,priority = 103)public void hello3EventBus(Person message){    Log.e("weiwei", "ASYNC_helloEventBus: "+Thread.currentThread().getName() );    mTextView3.setText(message.getName());}结果:ASYNC_helloEventBus: pool-2-thread-4BACKGROUND_helloEventBus: pool-2-thread-4MAIN_helloEventBus: mainPOSTING_helloEventBus: main

事件拦截

 @Subscribe(threadMode = ThreadMode.ASYNC,priority = 103)    public void hello3EventBus(Person message){        EventBus.getDefault().cancelEventDelivery(mPerson) ;        Log.e("weiwei", "ASYNC_helloEventBus: "+Thread.currentThread().getName() );        mTextView3.setText(message.getName());    }结果:BACKGROUND_helloEventBus: pool-2-thread-1MAIN_helloEventBus: mainPOSTING_helloEventBus: main

这个结果和有序广播的拦截机制不一样,哪个订阅事件拦截了,他就不会在接受这个事件。感觉有点鸡肋。

EventBus黏性事件

EventBus除了普通事件也支持粘性事件,这个有点类似广播分类中的粘性广播。本身粘性广播用的就比较少,为了方便理解成订阅在发布事件之后,但同样可以收到事件。订阅/解除订阅和普通事件一样,但是处理订阅函数有所不同,需要注解中添加sticky = true

@Subscribe(threadMode = ThreadMode.MAIN,sticky = true) //在ui线程执行public void onDataSynEvent(DataSynEvent event) {    Log.e(TAG, "event---->" + event.getCount());}

发送粘性事件

EventBus.getDefault().postSticky(new DataSynEvent());

对于粘性广播我们都比较清楚属于常驻广播,对于EventBus粘性事件也类似,我们如果不再需要该粘性事件我们可以移除

EventBus.getDefault().removeStickyEvent(new DataSynEvent());

或者调用移除所有粘性事件

 EventBus.getDefault().removeAllStickyEvents();

EventBus processor使用

EventBus提供了一个EventBusAnnotationProcessor注解处理器来在编译期通过读取@Subscribe()注解并解析,
处理其中所包含的信息,然后生成java类来保存所有订阅者关于订阅的信息,这样就比在运行时使用反射来获得这些订阅者的
信息速度要快.

  1. 具体使用:在build.gradle中添加如下配置

    buildscript {dependencies {      classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' }}apply plugin: 'com.neenbedankt.android-apt'dependencies {    compile 'org.greenrobot:eventbus:3.0.0'    apt 'org.greenrobot:eventbus-annotation-processor:3.0.1'}apt {    arguments {        eventBusIndex "com.whoislcj.eventbus.MyEventBusIndex"    }}
  2. 使用索引
    此时编译一次,自动生成生成索引类。在\build\generated\source\apt\PakageName\下看到通过注解分析生成的索引类,这样我们便可以在初始化EventBus时应用我们生成的索引了。
    自动生成的代码

        /** This class is generated by EventBus, do not edit. */public class MyEventBusIndex implements SubscriberInfoIndex {    private static final Map<Class<?>, SubscriberInfo> SUBSCRIBER_INDEX;    static {        SUBSCRIBER_INDEX = new HashMap<Class<?>, SubscriberInfo>();        putIndex(new SimpleSubscriberInfo(com.whoislcj.testhttp.MainActivity.class, true, new SubscriberMethodInfo[] {            new SubscriberMethodInfo("onDataSynEvent", com.whoislcj.testhttp.eventBus.DataSynEvent.class,                    ThreadMode.MAIN, 100, false),            new SubscriberMethodInfo("onDataSynEvent1", com.whoislcj.testhttp.eventBus.TestEvent.class, ThreadMode.MAIN,                    0, true),        }));    }    private static void putIndex(SubscriberInfo info) {        SUBSCRIBER_INDEX.put(info.getSubscriberClass(), info);    }    @Override    public SubscriberInfo getSubscriberInfo(Class<?> subscriberClass) {        SubscriberInfo info = SUBSCRIBER_INDEX.get(subscriberClass);        if (info != null) {            return info;        } else {            return null;        }    }}
  3. 添加索引到EventBus默认的单例中

    EventBus.builder().addIndex(new MyEventBusIndex()).installDefaultEventBus();

参考 ###

http://www.cnblogs.com/whoislcj/p/5595714.html

http://blog.csdn.net/harvic880925/article/details/40787203

原创粉丝点击