乐趣区

关于android:Android-第三方的框架EventBus

Android 第三方的框架 EventBus

一:介绍
EventBus 是一种用于 Android 的事件公布 - 订阅总线,它简化了应用程序内各个组件之间进行通信的复杂度,尤其是碎片之间进行通信的问题,能够防止因为应用播送通信而带来的诸多不便。
EventBus 能够代替 Android 传统的 Intent,Handler,Broadcast 或接口函数, 在 Fragment,Activity,Service 线程之间传递数据,执行办法。
二:应用
1. 增加依赖
在 app 下的 build.gradle 下增加依赖:

dependencies{

 //eventbus 增加依赖
    implementation 'org.greenrobot:eventbus:3.2.0'// 第一步:增加依赖
    }

2. 意识 EventBus

三个角色:

  • Event: 事件,它能够是任意类型,EventBus 会依据事件类型进行全局告诉。
  • Publisher: 事件的发布者,能够在任意线程中公布事件。个别状况下,应用 EventBus.getDefault()就能够失去一个 EventBus 对象,而后调用 post(Object)办法即可。
  • Subscriber: 事件订阅者,在 EventBus 3.0 之前咱们必须定义以 onEvent 结尾的那几个办法,别离是 onEvent、onEventMainThread、onEventBackgroundThread 和 onEventAsync,而在 3.0 之后事件处理的办法名能够随便取,不过须要加上注解 @subscribe,并且指定线程模型,默认是 POSTING。(须要注册事件的订阅者:EventBus.getDefault().register(this);EventBus.getDefault().unregister(this);this 传递的是事件的订阅者 Subscriber 事件公布了,如果咱们须要咱们须要注册订阅它)
    四种线程模型
    EventBus3.0 有四种线程模型,别离是:
  • POSTING: 默认,示意事件处理函数的线程跟公布事件的线程在同一个线程
  • MAIN: 示意事件处理函数的线程在主线程(UI 线程), 因而在这里不能进行耗时操作。这是次要应用的线程模型
  • BACKGROUND: 示意事件处理函数的线程在后盾线程,因而不能进行 UI 操作。如果公布事件的线程是主线程(UI 线程),那么事件处理函数将会开启一个后盾线程,如果果公布事件的线程是在后盾线程,那么事件处理函数就应用该线程。
  • ASYNC:示意无论事件公布的线程是哪一个,事件处理函数始终会新建一个子线程运行,同样不能进行 UI 操作。

3. 定义事件
封装一个 JavaBean 对象,定义事件对象

// 抉择 Tab 事件
public class ChooseTabEvent {
    private int tabId;

    public ChooseTabEvent(@IdRes int tabId) {this.tabId = tabId;}

    public int getTabId() {return tabId;}

    public void setTabId(int tabId) {this.tabId = tabId;}
}

4. 公布一个事件
在 UI 线程中公布一个事件

 EventBus.getDefault().postSticky(new ChooseTabEvent(0));// 抉择 Tab,公布了粘连事件

4. 解决一个事件
在处理事件的中须要注册事件,勾销事件注册

public class RedActivity extends BaseActivity {
@Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {EventBus.getDefault().register(this);
 }
 
 
 @Subscribe(threadMode = ThreadMode.MAIN,sticky = true)
    public void chooseTabEvent(ChooseTabEvent event){//3.0 当前办法能够自定义,这是解决了一个粘连事件,黏性事件 sticky=true
        if (event.getTabId()==0){
            LogUtils.i(
                    "抉择底部 tab:"
                            + BOTTOM_TAB_ID_ARRAY.keyAt(BOTTOM_TAB_ID_ARRAY.indexOfValue(R.id.tab_main)));
            bottomTab.setSelectedItemId(R.id.tab_main);
        }
    }
    
    
     @Override
    protected void onDestroy() {super.onDestroy();
        EventBus.getDefault().unregister(this);
    }
    
    }

黏性事件:所谓的黏性事件,就是指发送了该事件之后再订阅者仍然可能接管到的事件。

5. 优先级
在 Subscribe 注解中总共有 3 个参数,下面咱们用到了其中的两个,这里咱们应用以下第三个参数,即 priority。它用来指定订阅办法的优先级,是一个整数类型的值,默认是 0,值越大示意优先级越大。在某个事件被公布进去的时候,优先级较高的订阅办法会首先承受到事件。

6.ProGuard 混同规定
这里 gitHub 上给的有

-keepattributes *Annotation*//keep 反射
-keepclassmembers class * {@org.greenrobot.eventbus.Subscribe <methods>;/// 这个牵涉到你的需要如何,如果你应用了 EventBus processor 进行减速,你就必须加上这个,只有有这个注解的类和办法都不混同,为反编译提供了便当。。。如果没有用到减速,这个就不必了}
-keep enum org.greenrobot.eventbus.ThreadMode {*;}
 
# And if you use AsyncExecutor:// 如果你应用了 ASYNC 异步线程
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {<init>(java.lang.Throwable);
}

7. 遇到的问题
1、若应用 EventBus 时出现异常:Subscriber class * and its super classes have no public methods with the @Subscribe annotation
报错的起因:应用 EventBus 的办法不是 public,且短少 @Subscribe 这个注解。
依照提醒改为 public,并且加上 @Subscribe 这个注解就 Ok 了
就是 EventBus.getDefault().register(this); 不在 public 办法中


8.EventBus 内存泄露
eventBus 注册的时候会持有 activity 的援用,咱们在 onDestroy 反注册。若咱们的 activity 产生异样或零碎内存不足对 activity 强制回收的时候将不会走 onDestroy。eventBus 持有 activity 的援用,因而产生内存透露。而且当咱们再次关上 activity 时 eventBus 又会从新注册一次。
解决办法:注册的时候先判断 activity 是否注册过

if (!EventBus.getDefault().isRegistered(this))
            EventBus.getDefault().register(this);

END: 对可控的事件放弃审慎,不可控的事件放弃乐观。人只能做本人能力范畴内的事件,承受这个事实,并且以乐观的心,去应答这所有

退出移动版