jetpack01.lifecycle与liveData

173 阅读4分钟

一.Lifecycle

lifecycle解决什么问题

lifecycle通过封装activity/fragment/service生命周期状态变更的通知过程来简化开发者对于生命周期事件处理的逻辑.

当业务需要观察activity和fragment的生命周期时,需要做以下三件事

  • 建立activity和fragment的基类,在基类中添加属性用于注册监听者
  • 添加生命周期的定义接口,并让业务类实现该接口.
  • 在activity和fragment生命周期变化时,发送生命周期变化的事件.

如果没有Lifecycle组件

public interface LifeCycleListener {
    void onActivityCreated(OXMonitoredActivity activity);

    void onActivityStarted(OXMonitoredActivity activity);

    void onActivityResumed(OXMonitoredActivity activity);

    void onActivityPaused(OXMonitoredActivity activity);

    void onActivityDestroyed(OXMonitoredActivity activity);

    void onActivityStopped(OXMonitoredActivity activity);
}

class OXMonitoredActivity extends AppCompatActivity{
    private final ArrayList<LifeCycleListener> listeners = new ArrayList<LifeCycleListener>();
    
    public void addLifeCycleListener(LifeCycleListener listener) {
        if (listeners.contains(listener)) {
            return;
        }
        listeners.add(listener);
    }

    public void removeLifeCycleListener(LifeCycleListener listener) {
        listeners.remove(listener);
    }
    
    @Override
    public void onCreate(){
        for(LifeCycleListener listener : listeners){
            listener.onActivityCreated(this)
        }
    }
    ...
}

class Bussiness implements LifeCycleListener{
    void onActivityCreated(OXMonitoredActivity activity){...}

    void onActivityStarted(OXMonitoredActivity activity){...}

    void onActivityResumed(OXMonitoredActivity activity){...}

    void onActivityPaused(OXMonitoredActivity activity){...}

    void onActivityDestroyed(OXMonitoredActivity activity){...}

    void onActivityStopped(OXMonitoredActivity activity){...}
    
    void init(){
        getActivity().addLifeCycleListener(this)
    }
}

lifecycle如何解决问题

lifecycle在android sdk中的一套组件,它包含的主要类包括LifecycleOwner,LifecycleObserver,Lifecycle和LifecycleRegistry.

  • 所有的activity和fragment的基类ComponentActivity和Fragment实现LifecycleOwner接口,它提供获取LifecycleRegistry的接口,负责生命周期监听者的注册.
  • 需要监听生命周期方法的业务实现LifeCycleObserver接口,并通过LifecycleRegistry注册,实际上就是Map中存放了监听者的弱引用.
  • 在activity和fragment的生命周期切换过程中,sdk通过遍历map中的监听者,将所有生命周期信息发送给监听者.
  • 监听者提供的注解方法,在addObserver时,注解处理器会自动解析并将注解方法加入到map中对特定的生命周期事件进行处理.

相比于用户自己现实生命周期监听,LifeCycle组件的优势在于:

  • 提供类公共的基类作为生命周期的注册节点,防止出现多重继承问题.
  • 系统实现了生命周期的方法发送,相比于用户实现更加全面
  • 注解实现的生命周期处理方法,更加简洁.
public interface LifecycleOwner {
    @NonNull
    Lifecycle getLifecycle();
}

public class ComponentActivity extends androidx.core.app.ComponentActivity implements LifecycleOwner{
    
    private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
    
    public Lifecycle getLifecycle() {
        return mLifecycleRegistry;
    }
}

public class Bussiness imlements LifeCycleObserver{
    void init(){
        getLifecycle().addObserver(this)
    }
    
    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    public void onResume(LifecycleOwner owner) {
        ...
    }
}

生命周期事件如何分发

在老版本中,是在activity运行的各个阶段添加了事件分发代码.新版本中,通过给activity添加了隐形的ReportFragment,当activity生命周期发生变化时,ReportFragment的生命周期方法会被触发,从而发送对应的事件.

public class ReportFragment extends Fragment{
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        dispatchCreate(mProcessListener);
        dispatch(Lifecycle.Event.ON_CREATE);
    }

    @Override
    public void onStart() {
        super.onStart();
        dispatchStart(mProcessListener);
        dispatch(Lifecycle.Event.ON_START);
    }

    @Override
    public void onResume() {
        super.onResume();
        dispatchResume(mProcessListener);
        dispatch(Lifecycle.Event.ON_RESUME);
    }

    @Override
    public void onPause() {
        super.onPause();
        dispatch(Lifecycle.Event.ON_PAUSE);
    }
}

生命周期状态机

WechatIMG100.png

LiveData

LiveData 出现的意义

  • LiveData是jetpack中可观察的数据存储器类.LiveData订阅LifecycleOwner , 同时被Observer订阅.它既是观察者也是被观察者.
  • 借助于Lifecycle,它用于在activity/fragment/service处于可用(started或者resume)状态时,将数据的变化状态发送给观察者,一般是一些UI界面.

liveData用法

LiveData<String> d = new MutableLiveData<>();
d.observe(this, new Observer<String>() {
    @Override
    public void onChanged(String s) {
        Log.d("live" , s);
    }
});

数据总线

将一系列的LiveData集合起来

public class NonStickyMutableLiveData<T> extends MutableLiveData {

    private boolean stickFlag=false;

    @Override
    public void observe( LifecycleOwner owner,  Observer observer) {
        super.observe(owner, observer);
        if(!stickFlag) {
            hook(observer);
            stickFlag=true;
        }
    }

    //在这里去改变onChange的流程
    private void hook(Observer<? super T> observer) {
        try {
            //1.得到mLastVersion
            //获取到LiveData的类中的mObservers对象
            //SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers
            Class<LiveData> liveDataClass = LiveData.class;
            Field mObserversField = liveDataClass.getDeclaredField("mObservers");
            mObserversField.setAccessible(true);


            //获取到这个成员变量的对象
            Object mObserversObject = mObserversField.get(this);
            //得到map对应的class对象
            Class<?> mObserversClass = mObserversObject.getClass();
            //获取到mObservers对象的get方法   entry
            Method get = mObserversClass.getDeclaredMethod("get", Object.class);
            get.setAccessible(true);
            //执行get方法   mObservers.get(observer)
            Object invokeEntry=get.invoke(mObserversObject,observer);
            //定义一个空的对象
            Object observerWraper=null;
            if(invokeEntry!=null && invokeEntry instanceof Map.Entry){
                observerWraper=((Map.Entry)invokeEntry).getValue();//ObserverWrapper
            }
            if(observerWraper==null){
                throw new NullPointerException("observerWraper is null");
            }
            //得到ObserverWrapper的类对象  编译擦除问题会引起多态冲突所以用getSuperclass
            //TODO:getClass()返回对应的当前正在运行时的类所对应的对
            Class<?> superclass = observerWraper.getClass().getSuperclass();//mLastVersion
            Field mLastVersion = superclass.getDeclaredField("mLastVersion");
            mLastVersion.setAccessible(true);
            //2.得到mVersion
            Field mVersion = liveDataClass.getDeclaredField("mVersion");
            mVersion.setAccessible(true);
            //3.把mVersion的数据填入到mLastVersion中
            Object mVersionValue=mVersion.get(this);
            mLastVersion.set(observerWraper,mVersionValue);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}


public class LiveDataBus {
    private Map<String, MutableLiveData<Object>> bus;

    private static LiveDataBus liveDataBus = new LiveDataBus();

    private LiveDataBus() {
        bus = new HashMap<>();
    }

    public static LiveDataBus getInstance() {
        return liveDataBus;
    }

    public synchronized <T> MutableLiveData<T> with(String key,Class<T> type,boolean sticky){
        if(!bus.containsKey(key)){
            if(sticky){
                bus.put(key, new MutableLiveData<Object>());
            }else {
                bus.put(key, new NonStickyMutableLiveData<Object>());
            }
        }
        return (MutableLiveData<T>) bus.get(key);
    }
}


LiveDataBus.getInstance().with("msg", String.class,true)
    .observe(this, new Observer<String>() {
        @Override
        public void onChanged(String s) {
            Log.i("LiveDataBus",s);
        }
    });
    
LiveDataBus.getInstance().with("msg",String.class,true).postValue("threadClick");


LiveData的粘性发送

LiveData在数据发送之后监听,仍然能够收到最新的数据,原因在于当activity/fragment/service进入到可见状态后,会依次触发LifecycleRegistry.dispatchEvent,LifecycleBoundObserver.onStateChanged,ObserverWrapper.activeStateChanged,LiveData.dispatchingValue