Jetpack(一)Lifecycle和LiveData
源码分析:JetPacks之Lifecycles原理
应用:JetPacks之数据传递工具
联系:JetPack之 LifeCycle LiveData
Lifecycle
- Lifecycle可以有效的避免内存泄漏和解决android生命周期的常见难题
- Lifecycle 是一个表示android生命周期及状态的对象
- LivecycleOwner 用于连接有生命周期的对象,如activity,fragment
- LivecycleObserver 用于观察查LifecycleOwner
基本使用
Lifecycle框架使用观察者模式实现观察者监听被观察者的生命周期的变化
定义被观察者>>
通过实现LifecycleOwner接口
ComponentActivity.png如上图:我们使用activity不需要再自己写实现接口的代码
定义观察者>>
通过实现LifecycleObserver接口
通过注解在观察者类中定义需要监听的生命周期
注:以下方法都会在被观察者生命周期变化时调用
@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里,这个类是一个自定义列表,用于保存观察者并可在遍历期间处理删除/添加。
AppCompatActivity
AppCompatActivity 实现了LifecycleOwner接口,同时持有实现了Lifecycle的LifecycleRegistry对象,这个对象就可以将其理解为观察者模式中的Observable,LifecycleRegistr聚合多个LifecycleObserver,生命周期改变时通知LifecycleObserver进行相应的方法调用。
-
ReportFragment
Commponent#ReportFragment.injectIfNeededIn
AppCompatActivity 继承的extends androidx.core.app.ComponentActivity中的onCretae方法ReportFragment.injectIfNeededIn(this);
就是在当前的Activity里添加一个ReportFragment。
ReportFragment#dispatch()
再看ReportFragment的生命周期函数
你会发现都调用了dispatch()方法,
LifecycleRegistry#handleLifecycleEvent
而dispatch()方法则会判断Activity是否实现了LifecycleOwner接口,如果实现了该接口就调用LifecycleRegister的handleLifecycleEvent()
这样生命周期的状态就会借由LifecycleRegistry通知给各个LifecycleObserver从而调用其中对应Lifecycle.Event的方法。这种通过Fragment来感知Activity生命周期的方法其实在Glide的中也是有体现的。
handleLifecycleEvent--->getStateAfter
回到handleLifecycleEvent方法中
State next = getStateAfter(event);
事件发生的时候,先得到当前activity应该出现的下一个状态
状态机流转
moveToState(next);
mState = next;更新现在的状态
sync();
backwardPass(lifecycleOwner);逆推
forwardPass(lifecycleOwner);
forwardPass(lifecycleOwner)
forwardPass(lifecycleOwner)方法中的细节
ObserverWithState observer = entry.getValue();
找到ObserverWithState 类
调用mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
生成观察者适配器
onStateChanged
接下来就是调用onStateChanged(),来通知 实现了 LifecycleObserver的类,生命周期发生了变化
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通知观察者
- 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()被调用
- postValue中 >>
切换线程到主线程中去执行setValue
LiveDataEventBus
通过一个集合统一管理所有的LiveData
设计中的BUG:
原来的执行顺序new LiveData-->绑定observer-->setValue执行onChanged
而我们的BUS在用时可能出现 new LiveData-->setValue执行onChanged-->绑定observer
处理方案,让第一次setValue不起效即可
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(三) 之 Room 与 ViewModel
Jetpack 之 ViewModel 原理