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:对可控的事情保持谨慎,不可控的事情保持乐观。人只能做自己能力范围内的事情,接受这个事实,并且以乐观的心,去应对这一切
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。