Android通信方案LiveDataBus笔记

一:通信方案总结,对比

1,Handler     优点:系统原生,能实现线程间通信;  缺点:高耦合,不利于维护,容易导致内存泄露和空指针;

2,Boadcast  优点:简单;  缺点:性能差,传播数据有限。打乱代码的执行逻辑;

3,Interface    优点:速度快,容易理解; 缺点:实现复杂,不利于维护;

4,rxBus         优点:效率高,无内存泄露; 缺点:基于rxjava,学习成本高且依赖包太大,rxjava2.2M;

5,EventBus  优点:使用简单;    缺点:混淆问题,无法感知组件生命周期,实现复杂;

6,LiveDataBus 优点:实现简单,代码量少,官方提供稳定的依赖代码,感知组件(Acitivity,Fragment,Servcie等)生命周期,不存在内存泄露

二:LiveDataBus结构图

Android通信方案LiveDataBus笔记_第1张图片

1,什么是发布-订阅模式?

定义:这个模式用来作为中间人,一个把发布者和订阅者架接在一起的代理。

2,什么是LiveData?

定义:一个数据持有类,持有数据并且这个数据可以被观察被监听,和其他observable不同的是,它是和Lifecycle是绑定的,在生命周期内使用有效,减少内存泄露和引用问题;

3,如何构建LiveDataBus;

LiveDataBus的设计和架构

LiveDataBus的组成

  • 消息
    消息可以是任何的Object,可以定义不同类型的消息,如Boolean、String。也可以定义自定义类型的消息。

  • 消息通道
    LiveData扮演了消息通道的角色,不同的消息通道用不同的名字区分,名字是String类型的,可以通过名字获取到一个LiveData消息通道。

  • 消息总线
    消息总线通过单例实现,不同的消息通道存放在一个HashMap中。

  • 订阅
    订阅者通过getChannel获取消息通道,然后调用observe订阅这个通道的消息。

  • 发布
    发布者通过getChannel获取消息通道,然后调用setValue或者postValue发布消息。

三:LiveData的优点

  • UI和实时数据保持一致,因为LiveData采用的是观察者模式,这样一来就可以在数据发生改变时获得通知,更新UI。

  • 避免内存泄漏,观察者被绑定到组件的生命周期上,当被绑定的组件销毁(destroy)时,观察者会立刻自动清理自身的数据。

  • 不会再产生由于Activity处于stop状态而引起的崩溃,例如:当Activity处于后台状态时,是不会收到LiveData的任何事件的。

  • 不需要再解决生命周期带来的问题,LiveData可以感知被绑定的组件的生命周期,只有在活跃状态才会通知数据变化。

  • 实时数据刷新,当组件处于活跃状态或者从不活跃状态到活跃状态时总是能收到最新的数据。

  • 解决Configuration Change问题,在屏幕发生旋转或者被回收再次启动,立刻就能收到最新的数据。

package test.pvj.com.livedatabusdemo;

import android.arch.lifecycle.LifecycleOwner;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.MutableLiveData;
import android.arch.lifecycle.Observer;
import android.os.Looper;
import android.support.annotation.NonNull;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

//SDK 25版本及以上
// def lifecycle_version = "1.1.1"
//implementation "android.arch.lifecycle:extensions:$lifecycle_version"
public class LiveDataBus {

    private static LiveDataBus mInstance;
    private static Map mLiveDatas = new HashMap<>();

    private LiveDataBus() {

    }

    public static LiveDataBus get() {
        if (mInstance == null) {
            synchronized (LiveDataBus.class) {
                if (mInstance == null) {
                    mInstance = new LiveDataBus();
                }
            }
        }
        return mInstance;
    }

    public  MyMutableLiveData with(String key ,Class type){
        if (!mLiveDatas.containsKey(key)){
            mLiveDatas.put(key,new MyMutableLiveData());
        }
        return mLiveDatas.get(key);
    }
    public MyMutableLiveData with(String key){
        return with(key,Object.class);
    }

    public  void post(String key, T t){
        if(Looper.getMainLooper() == Looper.myLooper()){
            with(key).setValue(t);
        }else {
            with(key).postValue(t);
        }
    }

    public static class MyMutableLiveData extends MutableLiveData {
        @Override
        public void observe(@NonNull LifecycleOwner owner, @NonNull Observer observer) {
            super.observe(owner, observer);
            try {
                hook(observer);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        private void hook(@NonNull Observer observer) throws Exception {
            //get wrapper's version
            Class classLiveData = LiveData.class;
            Field fieldObservers = classLiveData.getDeclaredField("mObservers");
            fieldObservers.setAccessible(true);
            Object objectObservers = fieldObservers.get(this);
            Class classObservers = objectObservers.getClass();
            Method methodGet = classObservers.getDeclaredMethod("get", Object.class);
            methodGet.setAccessible(true);
            Object objectWrapperEntry = methodGet.invoke(objectObservers, observer);
            Object objectWrapper = null;
            if (objectWrapperEntry instanceof Map.Entry) {
                objectWrapper = ((Map.Entry) objectWrapperEntry).getValue();
            }
            if (objectWrapper == null) {
                throw new NullPointerException("Wrapper can not be bull!");
            }
            Class classObserverWrapper = objectWrapper.getClass().getSuperclass();
            Field fieldLastVersion = classObserverWrapper.getDeclaredField("mLastVersion");
            fieldLastVersion.setAccessible(true);
            //get livedata's version
            Field fieldVersion = classLiveData.getDeclaredField("mVersion");
            fieldVersion.setAccessible(true);
            Object objectVersion = fieldVersion.get(this);
            //set wrapper's version
            fieldLastVersion.set(objectWrapper, objectVersion);
        }
    }
} 
  

注册订阅

LiveDataBus.get()
        .with("key_test", String.class)
        .observe(this, new Observer() {
            @Override
            public void onChanged(@Nullable String s) {
            }
        });

发送消息:

LiveDataBus.get().with("key_test").setValue(s);

更详细的参考链接文章:https://tech.meituan.com/2018/07/26/android-livedatabus.html。

里面的github demo例子有点多,容易让开始看的人迷糊。

你可能感兴趣的:(Android进阶笔记)