一,事件总线
1,什么是事件总线
简单讲就是组件间数据的通信,例如从Activity传数据到Fragment
2,常见解决方案
| 通信方案 |
易用性 |
性能 |
感知生命周期 |
依赖第三方库 |
| Handler |
差 |
优 |
否 |
否 |
| Broadcast |
差 |
差 |
否 |
否 |
| Interface |
差 |
优 |
否 |
否 |
| EventBus |
优 |
优 |
否 |
是 |
| RxBus |
优 |
优 |
否 |
是 |
| LiveDataBus |
优 |
优 |
是 |
否 |
简单总结 :
Handler: 使用时匿名内部类易造成内存泄露(非静态内部类持有外部类的引用,然后在Handler做耗时操作,就会造成引用回收不了)
BoroadCast: 可读性不好,而且性能比较差,主要是消耗资源比较多,慢
Interface: 可维护性比较差 例如:从A到B到C到D,如果从A传数据可能需要在B,C,D都需要创建一个方法进行方法回调
EventBus: 需要注册,注销,如果忘了注销易造成内存泄露,同时不可感知生命周期,同时依赖第三方增大了apk的大小
RxBus: 与EventBus一样需要注册,注销,不可感知生命周期,依赖Rxjava增大apk大小
LiveDataBus: 只需要注册,因为可感知生命周期所以不需要注销,属于官方组件所以不需要依赖第三方,同时官方维护比较稳定
二,LiveData源码解析
1,观察者模式
角色:
被观察者:LiveData
观察者:实现了LifecycleOwner的Activity,Fragment之类
常用方法:
添加观察者:observe
移除观察者:removeObservers
发布:setValue,postValue
2,感知组件的生命周期是怎么实现的?
简单说就是:
LiveData.observe方法里面会传一个LifecycleOwner和一个Observer的回调,而我们常用的Activity和Fragment默认已经实现了LifecycleOwner,这样就建立起来了关联
具体的逻辑:
1.1, SupportActivity中增加一个Fragment专门用来绑定Activity的生命周期
onCreate方法中ReportFragment.injectIfNeededIn(this);
1.2,ReportFragment中生命周期绑定,这里只说主线,具体的细节大家可以对着源码来看
ReoprtFragment:
onStart();
dispatch(Lifecycle.Event.ON_START);
LifecycleRegistry
handleLifecycleEvent(event)
moveToState(next);
sync();
backwardPass(lifecycleOwner);
ObserverWithState
dispatchEvent(lifecycleOwner, upEvent(observer.mState));
LiveData
onStateChanged
activeStateChanged(shouldBeActive());
dispatchingValue(this);
considerNotify(initiator);
Observer
onChanged
3,为什么感知生命周期就可以不用注销呢?
LiveData的onStateChanged方法中可以看到如果当前的状态为DESTROYED就会移出Observer,这样就不用我们手动注销了
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
4,有什么需要优化的?
LiveData的setValue和postValue无论当前的值有没有变化都会强制刷新,但是有些场景只有变化的时候才刷新,这样我们可以节省资源,所以我们可以继承LiveData然后定义两个方法专门用来处理只有变化的时候才刷新
三,LiveDataBus架构
1,事件总线,需要订阅和发布也就是观察者,而LiveData刚好就是观察者模式,每个事件我们生成一个LiveData然后保存map里面,这样要订阅的时候直接从map里面拿就行了
2,事件总线是全局的,所以这里我们使用单例就可以了,专门用来管理map
四,手写LiveDataBus
4.1 版本一
实现的功能
1,发送,接受功能
可以优化的点
1,默认是粘性事件,改为注册之后才能接受到事件
2,类型转换异常造成的崩溃,利用装饰者设计模式包装下,对observe方法进行try...catch
3,上面说到LiveData可以优化,所以我们使用优化后的LiveData
4, 同时可以兼容粘性事件
5,发送默认消息
4.2 版本二
实现的功能
1,去粘性事件
1,当前页先observe,再setvalue
2,跳到其他页,先setValue,再observe()
2,防止类型转换异常造成的崩溃
3,LiveData的优化:就是之前发送过的消息,就不需要再接受了,相当于数据如果没有刷新的话就不需要刷新
4, 同时可以兼容粘性事件
5,发送默认消息
可以优化的点
1,Map管理的事件多了之后,我们可以定义方法清空,达到内存优化的目的
2,现在延迟发送,做的时候需要放在框架外,我们可以在框架内使用handler,或者协程来实现
3,去反射:现在Android对反射管理比较严,所以在版本兼容方面,我们尽量少用反射
4,事件Key没有约束,造成了我们在开发时不规范,可能到处都会写,要找一个事件可能要全局查找,我看他们是通过定义一个枚举,在值 上然后加注解,并指定类型,生成一个统一的类,然后从这个统一的类里面取不同的LiveData,相当于加一个了约束,每次必须在这个类里面添加一个KEY和指定类型
5,多线程发送数据造成丢失,具体还没有验证
6,支持跨进程