Android livedata原理解析之自己实现一个简单的LiveData

LiveData其实就是通过管理生命周期来实现当视图不可见时不渲染数据,当视图可见时再渲染数据.当在一个Activity发送一个网络请求后,立马切到另一个界面或都按下Home键,使得视图不可见..这个时候网络请求还在进行,当网络请求完成后,会判断这个界面是活跃状态还是不活跃状态,如果是不活跃状态则把数据保存在一个缓存集合里面,当这个视图可见时,就会回调其onStart方法,这里我们就可以监听到,然后将缓存数据显示到界面..

那么自己也写一个

创建一个生命周期接口

public interface Lifecycle {
    void onCreate(int activityCode);
    void onStart(int activityCode);
    void onStop(int activityCode);
    void onPause(int activityCode);
    void onDetach(int activityCode);
}

创建一个自己的LiveData类并实现Lifecycle

public class LiveData implements Lifecycle {
}

监听事件,我们肯定需要一个观察者,创建一个

public abstract class Observer {
    //活跃状态  可能收到消息
    static final int STATE_ACTIVE = 1;

    //暂停状态,不能收到消息
    static final int STATE_ONPAUSE = 2;

    //销毁状态
    static final int STATE_ONDESTORY = 3;
    //初始化状态
    static final int STATE_ONINIT = 0;


    private int state = STATE_ONINIT;

    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
    }

    public abstract void onChanged(T t);

}

我们LiveData肯定要管理所有注册的观察者,所以里面肯定有个管理集合,还要提供一个注册的方法

//  Integer是我们Activity的hashcode值
private Map> observers = new HashMap<>();

//进行注册
public void observe(FragmentActivity activity, Observer observer) {
       
     observers.put(activity.hashCode(), observer);
}

最后就是要设置值来达到显示数据的作用

public void setValue(T value) {
       
        for (Map.Entry> entry : observers.entrySet()) {
            Observer observer = entry.getValue();
            Integer activityCode = entry.getKey();
            observer.onChanged(value);
    }

为样所有注册了的观察都就都能收到数据.

现在来完成怎样管理生命周期

一般管理生命周期都是一个道理,用一个没有界面的fragment来完成,我们这也一样创建一个LifeFragment

public class LifeFragment extends Fragment {


    private Lifecycle mLifecycle;

    private int activityCode;
    public void setLifecycle(Lifecycle lifecycle){
        this.mLifecycle = lifecycle;
    }

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

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


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

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

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

然后回来我们LiveData类里面的注册方法里面,应该添加创建LifeFragment方法并设置监听

public void observe(FragmentActivity activity, Observer observer) {
        FragmentManager fm = activity.getSupportFragmentManager();
        observers.put(activity.hashCode(), observer);
        LifeFragment fragment = (LifeFragment) fm.findFragmentByTag("luckly.ancely.com.commonentmodule");
        if (fragment == null) {
            fragment = new LifeFragment();
            fm.beginTransaction().add(fragment, "luckly.ancely.com.commonentmodule").commitAllowingStateLoss();
        }

        fragment.setLifecycle(this);
}

这样我们就可以管理我们Actiity的生命周期了.这样就可以在不同的生命周期里面设置数据状态,如下

    @Override
    public void onCreate(int activityCode) {
        observers.get(activityCode).setState(Observer.STATE_ONINIT);
    }

    @Override
    public void onStart(int activityCode) {
        observers.get(activityCode).setState(Observer.STATE_ACTIVE);
    }

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

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

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

然后在setValue方法里也要对不同的状态进行不一样的判断 完整代码如下

    public void setValue(T value) {
        List destory = new ArrayList<>();
        for (Map.Entry> entry : observers.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 (cacheValue.get(activityCode) == null) {
                    cacheValue.put(activityCode,new ArrayList());
                }
                if (!cacheValue.get(activityCode).contains(value)) {
                   cacheValue.get(activityCode).add(value);
                }
            }
            //如果界面已经销毁了,则把其添加到销毁集合里,因为这是在遍历map集合,如果不能直接删除
            if (observer.getState() == Observer.STATE_ONDESTORY) {
                destory.add(observer);
            }
        }
        for (Observer observer : destory) {//最后把destory数据消除
            observers.remove(observer);
        }
    }

最后在我们的onStart回调里面设置数据

    @Override
    public void onStart(int activityCode) {
        observers.get(activityCode).setState(Observer.STATE_ACTIVE);
        if (cacheValue.get(activityCode) == null||cacheValue.get(activityCode).size()==0) {
            return;
        }
        for (T t : cacheValue.get(activityCode)) {
            observers.get(activityCode).onChanged(t);
        }
        cacheValue.clear();
    }

这样我们自己的LiveData就全部实现了.贴一个LiveData全部代码

package luckly.ancely.com.commoentmodule.event;

import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class LiveData implements Lifecycle {
    //Integer activity地址
    private Map> observers = new HashMap<>();
    private Map> cacheValue = new HashMap<>();

    public void observe(FragmentActivity activity, Observer observer) {
        FragmentManager fm = activity.getSupportFragmentManager();
        observers.put(activity.hashCode(), observer);
        LifeFragment fragment = (LifeFragment) fm.findFragmentByTag("luckly.ancely.com.commonentmodule");
        if (fragment == null) {
            fragment = new LifeFragment();
            fm.beginTransaction().add(fragment, "luckly.ancely.com.commonentmodule").commitAllowingStateLoss();
        }

        fragment.setLifecycle(this);
    }

    public void setValue(T value) {
        List destory = new ArrayList<>();
        for (Map.Entry> entry : observers.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 (cacheValue.get(activityCode) == null) {
                    cacheValue.put(activityCode,new ArrayList());
                }
                if (!cacheValue.get(activityCode).contains(value)) {
                   cacheValue.get(activityCode).add(value);
                }
            }

            if (observer.getState() == Observer.STATE_ONDESTORY) {
                destory.add(observer);
            }
        }
        for (Observer observer : destory) {
            observers.remove(observer);
        }
    }

    @Override
    public void onCreate(int activityCode) {
        observers.get(activityCode).setState(Observer.STATE_ONINIT);
    }

    @Override
    public void onStart(int activityCode) {
        observers.get(activityCode).setState(Observer.STATE_ACTIVE);
        if (cacheValue.get(activityCode) == null||cacheValue.get(activityCode).size()==0) {
            return;
        }
        for (T t : cacheValue.get(activityCode)) {
            observers.get(activityCode).onChanged(t);
        }
        cacheValue.clear();
    }

    @Override
    public void onStop(int activityCode) {
        observers.get(activityCode).setState(Observer.STATE_ONPAUSE);

    }

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

    @Override
    public void onDetach(int activityCode) {
        observers.remove(activityCode);
        cacheValue.clear();
    }
}

 

你可能感兴趣的:(Android,LiveData,ViewModel)