JetpackPack 知识Jetpack知识图谱

Jetpack(一)Lifecycle和LiveData

2021-01-18  本文已影响0人  zcwfeng

源码分析:JetPacks之Lifecycles原理
应用:JetPacks之数据传递工具
联系:JetPack之 LifeCycle LiveData

Lifecycle

基本使用

Lifecycle框架使用观察者模式实现观察者监听被观察者的生命周期的变化

定义被观察者>>

通过实现LifecycleOwner接口

ComponentActivity.png

如上图:我们使用activity不需要再自己写实现接口的代码

定义观察者>>

通过实现LifecycleObserver接口

BasePresenter.png

通过注解在观察者类中定义需要监听的生命周期

注:以下方法都会在被观察者生命周期变化时调用
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    void onCreateX(LifecycleOwner owner) {

    }


    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    void onStartX(LifecycleOwner owner) {
    }


    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    void onStop(LifecycleOwner owner) {
    }


    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    void onResume(LifecycleOwner owner) {
    }


    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    void onPause(LifecycleOwner owner) {
    }


    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    void onDestory(LifecycleOwner owner) {
    }


    @OnLifecycleEvent(Lifecycle.Event.ON_ANY)
    void onAny(LifecycleOwner owner) {
    }

完成订阅关系>>

在activity中使用

被观察者.addObserver(观察者)
getLifecycle().addObserver(presenter);

环境配置>>

自己引入
dependencies {
  implementation "androidx.lifecycle:lifecycle-runtime:2.0.0"
  implementation "androidx.lifecycle:lifecycle-extensions:2.0.0"
  implementation "androidx.lifecycle:lifecycle-common-java8:2.0.0"
  annotationProcessor  "androidx.lifecycle:lifecycle-compiler:2.0.0"
}

核心原理

LifecycleRegister#addObserver

看一下LifecycleRegister 类中的addObserver方法这里你会发现生成了一个ObserverWithState,然后放入FastSafeIterableMap里,这个类是一个自定义列表,用于保存观察者并可在遍历期间处理删除/添加。

  1. AppCompatActivity

AppCompatActivity 实现了LifecycleOwner接口,同时持有实现了Lifecycle的LifecycleRegistry对象,这个对象就可以将其理解为观察者模式中的Observable,LifecycleRegistr聚合多个LifecycleObserver,生命周期改变时通知LifecycleObserver进行相应的方法调用。

  1. ReportFragment Commponent#ReportFragment.injectIfNeededIn

AppCompatActivity 继承的extends androidx.core.app.ComponentActivity中的onCretae方法ReportFragment.injectIfNeededIn(this);
就是在当前的Activity里添加一个ReportFragment。

  1. ReportFragment#dispatch()

再看ReportFragment的生命周期函数
你会发现都调用了dispatch()方法,

  1. LifecycleRegistry#handleLifecycleEvent

而dispatch()方法则会判断Activity是否实现了LifecycleOwner接口,如果实现了该接口就调用LifecycleRegister的handleLifecycleEvent()
这样生命周期的状态就会借由LifecycleRegistry通知给各个LifecycleObserver从而调用其中对应Lifecycle.Event的方法。这种通过Fragment来感知Activity生命周期的方法其实在Glide的中也是有体现的。

  1. handleLifecycleEvent--->getStateAfter

回到handleLifecycleEvent方法中
State next = getStateAfter(event);
事件发生的时候,先得到当前activity应该出现的下一个状态

  1. 状态机流转

moveToState(next);
mState = next;更新现在的状态
sync();
backwardPass(lifecycleOwner);逆推
forwardPass(lifecycleOwner);

state.png
  1. forwardPass(lifecycleOwner)

forwardPass(lifecycleOwner)方法中的细节
ObserverWithState observer = entry.getValue();
找到ObserverWithState 类
调用mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
生成观察者适配器

  1. onStateChanged

接下来就是调用onStateChanged(),来通知 实现了 LifecycleObserver的类,生命周期发生了变化

  1. ReflectiveGenericLifecycleObserver

查看实现类
ReflectiveGenericLifecycleObserver。onStateChanged()

ReflectiveGenericLifecycleObserver。的构造方法中就把presenter中的方法和注解保存了下来
再通过onStateChanged()进行生命周期的方法的调用

源码分析 JetPacks之Lifecycles原理

应用 JetPacks之数据传递工具

Demo JetPack之 LifeCycle LiveData

LiveData

LiveData是一种具有生命周期感知能力的可观察数据持有类
LiveData可以保证屏幕上的显示内容和数据一直保持同步
特点:
1.LiveData了解UI界面的状态,如果activity不在屏幕上显示,livedata不会触发没必要的界面更新,如果activity已经被销毁,会自动清空与observer的连接,意外的调用就不会发生
2.LiveData是一个LifecycleOwner,他可以直接感知activity或fragment的生命周期

基本使用

定义LifeData >>

项目中livedata一般都存放在ViewModel中,以保证app配置变更时,数据不会丢失

举个例子:

public class NameViewModel extends ViewModel {
    public int i = 0;
    private MutableLiveData<String> currentName;
    public MutableLiveData<String> getCurrentName(){
        if(currentName==null){
            currentName=new MutableLiveData<>();
        }
        return currentName;
    }
}

使用流程 >>

定义观察者用以观察livedata中的数据变化

//需要一个观察者来观察数据
        Observer observer=new Observer<String>(){
            @Override
            public void onChanged(String s) {
                nameTextView.setText(s);
            }
        };

livedata订阅observer

        //获取到viewmodel
        model= ViewModelProviders.of(this).get(NameViewModel.class);
        //取出livedata完成订阅
        model.getCurrentName().observe(this,observer);

livedata发送消息通知observer更新数据

model.getCurrentName().setValue(anotherName);
以上代码会回调observer中的onChanged方法

使用注意:

setValue只能在主线程运行

postValue只能在子线程中运行

核心原理

1.observe做为入口>>

使用LifecycleBoundObserver把观察者和被观察者包装在一起
绑定wrapper作为观察者

绑定完成后,使用setValue与postValue通知观察者

  1. setValue中 >>

-------dispatchingValue(null)
if (initiator != null)
参数传null和不传null的区别就是如果传null将会通知所有的观察者,反之仅仅通知传入的观察者。
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
通知所有的观察者通过遍历 mObservers ,将所有的 ObserverWrapper 拿到,实际上就是我们上面提到的 LifecycleBoundObserver,通知观察者调用considerNotify()方法,这个方法就是通知的具体实现了。

-------considerNotify()

先用2个if判断出被观察者对应的activity状态是否为显示
发送通知 onChanged()被调用

  1. postValue中 >>

切换线程到主线程中去执行setValue

LiveDataEventBus

通过一个集合统一管理所有的LiveData
设计中的BUG:
原来的执行顺序new LiveData-->绑定observer-->setValue执行onChanged
而我们的BUS在用时可能出现 new LiveData-->setValue执行onChanged-->绑定observer
处理方案,让第一次setValue不起效即可

参考Github

LiveDataBus

package top.zcwfeng.jetpack.utils;

import androidx.lifecycle.MutableLiveData;

import java.util.HashMap;
import java.util.Map;

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) {
        if(!bus.containsKey(key)){
            bus.put(key,new MutableLiveData<Object>());
        }
        return (MutableLiveData<T>)bus.get(key);
    }
}

LiveDataXBus 解除 LiveDataBus 粘性问题,某些场景需要

/**
 * 解除 LiveDataBus 粘性问题,某些场景需要
 */
public class LiveDataBusX {
    //存放订阅者
    private Map<String, BusMutableLiveData<Object>> bus;

    private static LiveDataBusX liveDataBus = new LiveDataBusX();

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

    public static LiveDataBusX getInstance() {
        return liveDataBus;
    }

    //注册订阅者,(存入map) Hook前用MutableLiveData
    public synchronized <T> BusMutableLiveData<T> with(String key, Class<T> type){
        if(!bus.containsKey(key)){
            bus.put(key,new BusMutableLiveData<Object>());
        }
        return (BusMutableLiveData<T>) bus.get(key);
    }

    public static class BusMutableLiveData<T> extends MutableLiveData<T> {
        @Override
        public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
            super.observe(owner, observer);
            hook(observer);
        }
        //在这里去改变onChange的流程
        private void hook(Observer<? super T> observer) {
            try {
                //1.得到mLastVersion
                //获取到LiveData的类中的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方法
                Method get = mObserversClass.getDeclaredMethod("get", Object.class);
                get.setAccessible(true);
                //执行get方法
                Object invokeEntry=get.invoke(mObserversObject,observer);
                //定义一个空的对象
                Object observerWraper=null;
                if(invokeEntry!=null && invokeEntry instanceof Map.Entry){
                    observerWraper=((Map.Entry)invokeEntry).getValue();
                }
                if(observerWraper==null){
                    throw new NullPointerException("observerWraper is null");
                }
                //得到ObserverWrapper的类对象  编译擦除问题会引起多态冲突所以用getSuperclass
                Class<?> superclass = observerWraper.getClass().getSuperclass();
                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();
            }
        }
    }

}

目录:

Jetpack(一)Lifecycle和LiveData
JetPacks之Lifecycles原理
JetPack之 LifeCycle LiveData

Jetpack(二)之DataBinding

Jetpack(三) 之 Room 与 ViewModel
Jetpack 之 ViewModel 原理

Jetpack (四) 之 Navigation
Jetpack Navigation 原理浅析

JetPack (五)之 Paging 分页库

Jetpack(六) 之 WorkManager
Jetpack WorkManager 原理

上一篇下一篇

猜你喜欢

热点阅读