源碼分析:JetPacks之Lifecycles原理
應用:JetPacks之數據傳遞工具
聯系:JetPack之 LifeCycle LiveData
Lifecycle
- Lifecycle可以有效的避免內存泄漏和解決android生命周期的常見難題
- Lifecycle 是一個表示android生命周期及狀態的對象
- LivecycleOwner 用于連接有生命周期的對象,如activity,fragment
- LivecycleObserver 用于觀察查LifecycleOwner
基本使用
Lifecycle框架使用觀察者模式實現觀察者監聽被觀察者的生命周期的變化
定義被觀察者>>
通過實現LifecycleOwner接口
如上圖:我們使用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 原理