1、了解LiveData
1>什么是LiveDate?
答:LiveData是Android官方提供的。LiveData是一个可以被观察的数据持有类,它可以感知并遵循Activity、Fragment或Service等组件的生命周期。正是由于LiveData对组件生命周期可感知特点,因此可以做到仅在组件处于生命周期的激活状态时才更新UI数据。(换成人话就是说:LiveData 是用来跨页(跨线程)通讯的类,官方给我们提供的,我们只管用就行。不用管生命周期带来的内存泄漏等相关问题)
2>LiveDate的优点
1、UI和实时数据保持一致 因为LiveData采用的是观察者模式,这样一来就可以在数据发生改变时获得通知,更新UI。
2、避免内存泄漏 观察者被绑定到组件的生命周期上,当被绑定的组件销毁(destroy)时,观察者会立刻自动清理自身的数据。
3、不会再产生由于Activity处于stop状态而引起的崩溃
2、LiveDataBus、EventBus和RxBus的比较
1>EventBus
2>RxBUs
在RxJava中有个Subject类,它继承Observable类,同时实现了Observer接口,因此Subject可以同时担当订阅者和被订阅者的角色,我们使用Subject的子类PublishSubject来创建一个Subject对象(PublishSubject只有被订阅后才会把接收到的事件立刻发送给订阅者),在需要接收事件的地方,订阅该Subject对象,之后如果Subject对象接收到事件,则会发射给该订阅者,此时Subject对象充当被订阅者的角色。
完成了订阅,在需要发送事件的地方将事件发送给之前被订阅的Subject对象,则此时Subject对象作为订阅者接收事件,然后会立刻将事件转发给订阅该Subject对象的订阅者,以便订阅者处理相应事件,到这里就完成了事件的发送与处理。
最后就是取消订阅的操作了,RxJava中,订阅操作会返回一个Subscription对象,以便在合适的时机取消订阅,防止内存泄漏,如果一个类产生多个Subscription对象,我们可以用一个CompositeSubscription存储起来,以进行批量的取消订阅。
3>LiveDataBus
实现代码
代码中有注释,就不在赘述
```
public final class LiveDataBus {
private final Map>bus;
private LiveDataBus() {
bus =new HashMap<>();
}
private static class SingletonHolder {
private static final LiveDataBusDEFAULT_BUS =new LiveDataBus();
}
public static LiveDataBusget() {
return SingletonHolder.DEFAULT_BUS;
}
public MutableLiveDatawith(String key, Class type) {
if (!bus.containsKey(key)) {
bus.put(key, new BusMutableLiveData<>());
}
return (MutableLiveData)bus.get(key);
}
public MutableLiveDatawith(String key) {
return with(key, Object.class);
}
/**
* 解决observeForever内存泄漏问题
*
* @param
*/
private static class ObserverWrapperimplements Observer {
private Observerobserver;
public ObserverWrapper(Observer observer) {
this.observer = observer;
}
@Override
public void onChanged(@Nullable T t) {
if (observer !=null) {
if (isCallOnObserve()) {
return;
}
observer.onChanged(t);
}
}
private boolean isCallOnObserve() {
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
if (stackTrace !=null && stackTrace.length >0) {
for (StackTraceElement element : stackTrace) {
if ("android.arch.lifecycle.LiveData".equals(element.getClassName()) &&
"observeForever".equals(element.getMethodName())) {
return true;
}
}
}
return false;
}
}
/**
* 解决 订阅者会收到订阅之前发布的消息 问题
*
* @param
*/
private static class BusMutableLiveDataextends MutableLiveData {
private MapobserverMap =new HashMap<>();
@Override
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer observer) {
super.observe(owner, observer);
try {
hook(observer);
}catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void observeForever(@NonNull Observer observer) {
if (!observerMap.containsKey(observer)) {
observerMap.put(observer, new ObserverWrapper(observer));
}
super.observeForever(observerMap.get(observer));
}
@Override
public void removeObserver(@NonNull Observer observer) {
Observer realObserver =null;
if (observerMap.containsKey(observer)) {
realObserver =observerMap.remove(observer);
}else {
realObserver = observer;
}
super.removeObserver(realObserver);
}
/**
* 利用hook技术修改源码的实现逻辑
*
* @param observer
* @throws Exception
*/
private void hook(@NonNull Observer observer)throws Exception {
//拿到LiveData
Class classLiveData = LiveData.class;
//找到LiveData中mObservers字段
Field fieldObservers = classLiveData.getDeclaredField("mObservers");
fieldObservers.setAccessible(true);
Object objectObservers = fieldObservers.get(this);
Class classObservers = objectObservers.getClass();
//调用mObservers的get方法
Method methodGet = classObservers.getDeclaredMethod("get", Object.class);
methodGet.setAccessible(true);
//调用get方法拿到mObservers中单个的Entry值
Object objectWrapperEntry = methodGet.invoke(objectObservers, observer);
Object objectWrapper =null;
if (objectWrapperEntryinstanceof Map.Entry) {
//拿到Observer
objectWrapper = ((Map.Entry) objectWrapperEntry).getValue();
}
if (objectWrapper ==null) {
throw new NullPointerException("Wrapper can not be bull!");
}
//拿到Observer的父类(ObserverWrapper)
Class classObserverWrapper = objectWrapper.getClass().getSuperclass();
Field fieldLastVersion = classObserverWrapper.getDeclaredField("mLastVersion");
fieldLastVersion.setAccessible(true);
//拿到LiveData中的mVersion
Field fieldVersion = classLiveData.getDeclaredField("mVersion");
fieldVersion.setAccessible(true);
Object objectVersion = fieldVersion.get(this);
//把observer.mLastVersion的值改为mVersion的值
fieldLastVersion.set(objectWrapper, objectVersion);
}
}
}
```
参考:手写LiveDataBus