手写LiveData

引言 :

  • 1 LiveData的使用方式
  • 2 手写LiveData
    1. LiveData+ViewModule 在项目中的结合使用

LiveData的类关系图相对比较简单,从上面的类图我们就能看到。和LiveData组件相关的类和接口有:LiveData类、Observer接口、GenericLifecycleObserver接口。LiveData类是个抽象类,但是它没有抽象方法,抽象类有个特点是:不能在抽象类中实例化自己。为什么LiveData会被定义成abstract而又没有抽象方法呢,这个…我也不知道,看了下LiveData的提交记录,是在将hasObservers()替换getObserverCount()方法时将LiveData改成了abstract,在此之前它是被定义为public,可以翻墙的可以看下这里的修改记录

  • MediatorLiveData继承自MutableLiveData,MutableLiveData继承自LiveData。MediatorLiveData可以看成是多个LiveData的代理,当将多个LiveData添加到MediatorLiveData,任何一个LiveData数据发生变化时,MediatorLiveData都会收到通知。
  • LiveData有个内部类LifecycleBoundObserver,它实现了GenericLifecycleObserver,而GenericLifecycleObserver继承了LifecycleObserver接口。在这里可以回顾下Lifecycle组件相关的内容。当组件(Fragment、Activity)生命周期变化时会通过onStateChanged()方法回调过来。
  • Observer接口就是观察者,其中定义了LiveData数据变化的回调方法onChanged()。
    想到 LifecycleListener 我们就想到生命周期的接管:
    1. 定义LifecycleListener
public interface LifecycleListener {
    public void onCreate(int activityCode);
    public void onStart(int activityCode);
    public void onPause(int activityCode);
    public void onDetach(int activityCode);
}
    1. 定义HolderFragment 去托管生命周期 由LifecycleListener 完成回调
public class HolderFragment extends Fragment {
    private int activityCode;
    private LifecycleListener lifecycleListener;

    public void setLifecycleListener(LifecycleListener lifecycleListener) {
        this.lifecycleListener = lifecycleListener;
    }

    public void onAttach(Activity activity) {
        super.onAttach(activity);
        activityCode = activity.hashCode();
        if (lifecycleListener != null) {
            lifecycleListener.onCreate(activityCode);
        }

    }
    public void onDetach() {
        super.onDetach();
        if (lifecycleListener != null) {
            lifecycleListener.onDetach(activityCode);
        }
    }
    @Override
    public void onStart() {
        super.onStart();
        if (lifecycleListener != null) {
            lifecycleListener.onStart(activityCode);
        }
    }

    @Override
    public void onPause() {
        super.onPause();
        if (lifecycleListener != null) {
            lifecycleListener.onPause(activityCode);
        }
    }

    @Override
    public void onStop() {
        super.onStop();


    }
}
    1. 定义observe 实现 事件的监听
   public void observe(Activity activity, Observer observer) {
        FragmentManager fm=activity.getFragmentManager();
        HolderFragment current = (HolderFragment) fm.findFragmentByTag("com.gyb.livedata");
        if (current == null) {
            current = new HolderFragment();
            fm.beginTransaction().add(current, "com.gyb.livedata").commitAllowingStateLoss();
        }
        current.setLifecycleListener(lifecycleListener);
        map.put(activity.hashCode(), observer);
    }

上面的代码 主要的思路是由当前的 页面 动态添加 fragement 将fragment 的生命周期回调出去。
并且将当前observer 缓存起来。

    1. lifecycleListener 去动态设置状态

    private LifecycleListener lifecycleListener = new LifecycleListener() {
        @Override
        public void onCreate(int activityCode) {
            map.get(activityCode).setState(Observer.STATE_INIT);
        }

        @Override
        public void onStart(int activityCode) {
            map.get(activityCode).setState(Observer.STATE_ACTIVE);
            if (mPendingDelayList.get(activityCode) == null) {
                return;
            }
            for (T t : mPendingDelayList.get(activityCode)) {
                map.get(activityCode).onChanged(t);
            }
            mPendingDelayList.get(activityCode).clear();
        }

        @Override
        public void onPause(int activityCode) {
            map.get(activityCode).setState(Observer.STATE_ONPAUSE);
        }

        @Override
        public void onDetach(int activityCode) {
            map.remove(activityCode);
        }

上面代码主要的思路是根据 fragment 的生命周期管理去动态添加移除注入的observer

  • 发送事件 setValue
 public void setValue(T value) {
        synchronized (this){
            List destoryList = new ArrayList<>();
            for (Map.Entry> entry : map.entrySet()) {
                Observer observer = entry.getValue();
                Integer activityCode = entry.getKey();
                if (observer.getState() == Observer.STATE_ACTIVE) {
                    observer.onChanged(value);
                }
                if (observer.getState() == Observer.STATE_ONPAUSE) {
                    if (mPendingDelayList.get(activityCode) == null) {
                        mPendingDelayList.put(activityCode, new ArrayList());
                    }
                    if (!mPendingDelayList.get(activityCode).contains(value)) {
                        mPendingDelayList.get(activityCode).add(value);
                    }
                }
                if (observer.getState() == Observer.STATE_DESTORY) {
                    destoryList.add(observer);
                }
            }
            for (Observer item : destoryList) {
                destoryList.remove(item);
            }
        }
    }

上面 将 添加的观察者 在用户可见 即 STATE_ACTIVE 时 去回调 onChanged

完整的 LiveData

public class  LiveData   {
    // how many observers are in active state
    private int mActiveCount = 0;
    static final int START_VERSION = -1;
    private HashMap< Integer,Observer> map = new HashMap<>();
    private HashMap> mPendingDelayList = new HashMap<>();
//    当前正在计划 对信道 发送的信息
    private volatile Object mPendingData;
    private int mVersion = START_VERSION;
    Handler handler = new Handler(Looper.getMainLooper());
    public void setValue(T value) {
        synchronized (this){
            List destoryList = new ArrayList<>();
            for (Map.Entry> entry : map.entrySet()) {
                Observer observer = entry.getValue();
                Integer activityCode = entry.getKey();
                if (observer.getState() == Observer.STATE_ACTIVE) {
                    observer.onChanged(value);
                }
                if (observer.getState() == Observer.STATE_ONPAUSE) {
                    if (mPendingDelayList.get(activityCode) == null) {
                        mPendingDelayList.put(activityCode, new ArrayList());
                    }
                    if (!mPendingDelayList.get(activityCode).contains(value)) {
                        mPendingDelayList.get(activityCode).add(value);
                    }
                }
                if (observer.getState() == Observer.STATE_DESTORY) {
                    destoryList.add(observer);
                }
            }
            for (Observer item : destoryList) {
                destoryList.remove(item);
            }
        }
    }
    public void postValue(final T value) {
        synchronized (this){
            handler.post(new Runnable() {
                @Override
                public void run() {
                    setValue(value);
                }
            });
        }
    }
    public void observe(Activity activity, Observer observer) {
        FragmentManager fm=activity.getFragmentManager();
        HolderFragment current = (HolderFragment) fm.findFragmentByTag("com.gyb.livedata");
        if (current == null) {
            current = new HolderFragment();
            fm.beginTransaction().add(current, "com.gyb.livedata").commitAllowingStateLoss();
        }
        current.setLifecycleListener(lifecycleListener);
        map.put(activity.hashCode(), observer);
    }

    private LifecycleListener lifecycleListener = new LifecycleListener() {
        @Override
        public void onCreate(int activityCode) {
            map.get(activityCode).setState(Observer.STATE_INIT);
        }

        @Override
        public void onStart(int activityCode) {
            map.get(activityCode).setState(Observer.STATE_ACTIVE);
            if (mPendingDelayList.get(activityCode) == null) {
                return;
            }
            for (T t : mPendingDelayList.get(activityCode)) {
                map.get(activityCode).onChanged(t);
            }
            mPendingDelayList.get(activityCode).clear();
        }

        @Override
        public void onPause(int activityCode) {
            map.get(activityCode).setState(Observer.STATE_ONPAUSE);
        }

        @Override
        public void onDetach(int activityCode) {
            map.remove(activityCode);
        }
    };
}

将 LiveData 封装成 LiveDataBus:

public class LiveDataBus  {
    private Map> bus = new HashMap<>();
    private static final LiveDataBus ourInstance = new LiveDataBus();
    public static LiveDataBus get() {
        return ourInstance;
    }

    private LiveDataBus() {
    }
    public  LiveData getChannel(String target, Class type) {
        if (!bus.containsKey(target)) {
            bus.put(target, new LiveData<>());
        }
        return (LiveData) bus.get(target);
    }
    public LiveData getChannel(String target) {
        return getChannel(target, Object.class);
    }
}

调用:

    @Override
    protected void loadData() {
        //注册监听
        LiveDataBus.get().getChannel("target",String.class).observe(this, s -> {
        });
    }

    /**
     * 发送事件
     */
    private void postValue(){
        LiveDataBus.get().getChannel("target").postValue("发送了一个事件");
    }

哈哈,就是这么简单 .

你可能感兴趣的:(手写LiveData)