最近了解到一個開源庫,uber的 AutoDispose,由于不經常使用RxJava,竟然不知道還有這么個東西,,它的主要作用就是在Activity或View銷毀不可用的時候自動取消RxJava的訂閱,也就是常用的Disposable切斷管道流, 取消訂閱,避免記憶體泄漏,AutoDispose將之前的Disposable.dispose()操作做了封裝,可以自動處理,
它的使用就不去詳細探索了,搜索一下就有一堆,這里主要探究一下AutoDispose的實作原理的關鍵技術點,既然它能在AC銷毀的時候自動取消,那么它是如何自動感知AC的生命周期的呢?
AutoDispose的簡單用法示例:
Observable.interval(1, TimeUnit.SECONDS)
.doOnDispose(new Action() {
@Override public void run() throws Exception {
Log.i(TAG, "Disposing subscription from onResume() with untilEvent ON_DESTROY");
}
})
.as(AutoDispose.<Long>autoDisposable(
AndroidLifecycleScopeProvider.from(this, Lifecycle.Event.ON_DESTROY)))//OnDestory時自動解綁
.subscribe(new Consumer<Long>() {
@Override public void accept(Long num) throws Exception {
Log.i(TAG, "Started in onResume(), running until in onDestroy(): " + num);
}
});
其中as回傳的還是一個Observable物件,關鍵是這一行:
AutoDispose.autoDisposable(
AndroidLifecycleScopeProvider.from(this, Lifecycle.Event.ON_DESTROY))
AndroidLifecycleScopeProvider.from(this, Lifecycle.Event.ON_DESTROY) 中的this是什么:

這個this實際上是LifecycleOwner這個介面,LifecycleOwner又是神馬?

是android提供的Lifecycle這個組件庫中的一個介面,同時還有一個LifecycleObserver觀察者介面,通過原始碼發現,support.v7包中的AppCompatActivity最終繼承自SupportActivity,SupportActivity實作了LifecycleOwner介面,support.v4包中的Fragment也實作了LifecycleOwner介面,AndroidX的ComponentActivity支持庫同樣也實作了LifecycleOwner介面:



所以這些類當中默認都能直接使用 AutoDispose ,那具體的生命周期檢測是如何做到的?
先看LifecycleObserver這個介面的簡單使用代碼:
import android.arch.lifecycle.Lifecycle;
import android.arch.lifecycle.LifecycleObserver;
import android.arch.lifecycle.OnLifecycleEvent;
import android.util.Log;
public class MyObserver implements LifecycleObserver {
private final static String TAG = MyObserver.class.getSimpleName();
@OnLifecycleEvent(Lifecycle.Event.ON_START)
public void ready(){
Log.e(TAG,"ON_START");
}
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
public void connectListener() {
Log.e(TAG,"ON_RESUME");
}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
public void disconnectListener() {
Log.e(TAG,"ON_PAUSE");
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
public void destroyListener() {
Log.e(TAG,"ON_DESTROY");
}
}
然后在Activity當中呼叫:getLifecycle().addObserver(new MyObserver());

運行,啟動AC,home回傳桌面,再回傳,再back關閉AC,列印輸出:

我們發現LifecycleOwner這個介面可以幫助我們擺脫Activity之外獨立監聽Activity的生命周期,
點擊 getLifecycle() 方法,發現:

沒錯,就是在SupportActivity類當中的 LifecycleRegistry這個類的物件

LifecycleRegistry 又是神馬?
預覽一下它的幾個方法:



LifecycleRegistry就像狀態機一樣,來管理和切換Ac的各個生命周期狀態的,每個生命周期都有狀態常量與之一一對應,那AC又是如何呼叫LifecycleRegistry的呢?
在 SupportActivity 的onCreate方法當中:
public class SupportActivity extends Activity implements LifecycleOwner, Component {
private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ReportFragment.injectIfNeededIn(this);
}
@CallSuper
protected void onSaveInstanceState(Bundle outState) {
this.mLifecycleRegistry.markState(State.CREATED);
super.onSaveInstanceState(outState);
}
關鍵是這一行:ReportFragment.injectIfNeededIn(this);,那這個 ReportFragment又是神馬?

就是一個Fragment類,而且不是v4包的,是原生包里的,

它的每個生命周期方法中都會呼叫 dispatch(Lifecycle.Event event) 方法:

這里呼叫了 LifecycleRegistry 的 handleLifecycleEvent 方法,而handleLifecycleEvent 方法當中其實就是進行對應生命周期狀態的切換了,我們知道Activity 會自動呼叫 Fragment 的生命周期,這樣就完成了生命周期的無感知監聽,利用了一個隱式的無UI界面的Fragment物件來巧妙的實作的,
上面是 SupportActivity 的,那普通 Activity 呢?怎么呼叫 LifecycleRegistry 的?
對于 26.1.0 以后的版本,你會發現,對于普通的 Activity,如果你想要使用 lifecycle,你只需要實作LifecycleOwner 介面即可,
其實是在 LifecycleDispatcher 類當中呼叫的:
class LifecycleDispatcher {
private static final String REPORT_FRAGMENT_TAG = "android.arch.lifecycle"
+ ".LifecycleDispatcher.report_fragment_tag";
private static AtomicBoolean sInitialized = new AtomicBoolean(false);
static void init(Context context) {
if (sInitialized.getAndSet(true)) {
return;
}
// 在 init 方法中,監聽全域 activity 的創建,從而來添加 fragment
((Application) context.getApplicationContext())
.registerActivityLifecycleCallbacks(new DispatcherActivityCallback());
}
@SuppressWarnings("WeakerAccess")
@VisibleForTesting
static class DispatcherActivityCallback extends EmptyActivityLifecycleCallbacks {
private final FragmentCallback mFragmentCallback;
DispatcherActivityCallback() {
mFragmentCallback = new FragmentCallback();
}
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
if (activity instanceof FragmentActivity) {
((FragmentActivity) activity).getSupportFragmentManager()
.registerFragmentLifecycleCallbacks(mFragmentCallback, true);
}
ReportFragment.injectIfNeededIn(activity);
}
@Override
public void onActivityStopped(Activity activity) {
if (activity instanceof FragmentActivity) {
markState((FragmentActivity) activity, CREATED);
}
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
if (activity instanceof FragmentActivity) {
markState((FragmentActivity) activity, CREATED);
}
}
//....
}
}
可以看到,它 在 init 方法中,通過 context.getApplicationContext() .registerActivityLifecycleCallbacks 監聽全域 activity 的創建,在 activity oncreate 的時候,呼叫 ReportFragment.injectIfNeededIn(activity) ,從而來添加 fragment,進而分發相應的事件,
那 LifecycleDispatcher.init 方法又是在哪里呼叫的呢?
public class ProcessLifecycleOwnerInitializer extends ContentProvider {
@Override
public boolean onCreate() {
LifecycleDispatcher.init(getContext());
ProcessLifecycleOwner.init(getContext());
return true;
}
它是在 ProcessLifecycleOwnerInitializer 的 onCreate 方法中呼叫的,而 ProcessLifecycleOwnerInitializer 是一個 ContentProvider,
而 ContentProvider 的 onCreate 方法優先于 Application 的 onCreate 執行,所以在 Application 之前我們就呼叫了 ProcessLifecycleOwnerInitializer init 方法,監聽了 Activity 的創建,當 Actiivty 創建的時候,會嘗試為 Activity 添加 ReportFragment,而 ReportFragment 會在 Activity 生命周期變化的時候幫助我們分發生命周期,
關于ContentProvider 的 onCreate 方法優先于 Application 的 onCreate 執行,可以參考這里,
大致程序,借用道友的一張圖:

另外,Application層級也能監聽app的狀態,使用 ProcessLifecycleOwner:
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
ProcessLifecycleOwner.get().getLifecycle().addObserver(new ApplicationObserver());
}
}
也就是說如果自己設計一個框架想監聽AC或App生命周期, 只需要接受一個 LifecycleOwner 引數即可,因為android系統多陣列件類都實作了這個介面,
參考鏈接:
https://www.jianshu.com/p/bd800c5dae30
https://blog.csdn.net/gdutxiaoxu/article/details/86660766
https://blog.csdn.net/yuzhangzhen/article/details/110409667
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/276653.html
標籤:其他
下一篇:并查集之擴展域
