Handling LifeCycle
android.arch.lifecycle 提供的類和接口,讓使用者構建能夠感知生命周期。
Lifecycle is a class that holds the information about the lifecycle state of a component (like an activity or a fragment) and allows other objects to observe this state.
根據Activity or fragment的生命周期自行調整類的行為通過觀察其狀態
Lifecycle uses two main enumerations to track the lifecycle status for its associated component:
AAC 中提供了LifeCycle 使用枚舉類來解決生命周期管理問題。
- 持有Activity/Fragment 生命周期類
- 通過接口LifecycleRegistryOwner /LifecycleObserver 注解事件@OnLifecycleEvent(),以及外部調用觀察者模式addObserver(mTx),來完成將(Activity/Fragment)”生命周期”共享給其他組件這么一件事
- 事件
生命周期事件由系統來分發,這些事件對應與Activity和Fragment的生命周期函數
(ON_CREATE,ON_START,ON_RESUME,ON_PAUSE,ON_STOP,ON_DESTROY)
- 狀態
LifeCycle的狀態,用於追蹤lifecycle對象: (INITIALIZED,DESTROYED,CREATED,STARTED,RESUMED)
ps:在STARTED和RESUMED 狀態是處於活躍狀態,只有在這兩個狀態下LivaData是會通知數據變化的。

ps 考慮一個問題:
LifeCycle 是如何感知到Activity或是Fragment的生命周期的呢?
因為AAC是基於MVVM架構的所以首先開一下 MVP和MVVM的感知生命周期操作。
(1)MVP感知生命周期的方法
最開始的attach和detach ,通過Activity或是Fragment中生命周期函數去關聯Presenter,之后判斷View是否是Active的來決定是否更新Ui。因為Retrofit和RxJava的興起,可以將Presenter中的動作變成一個流事件。通過RxJava特效通過解除訂閱的方式來控制Presenter中的更新Ui的動作。后面有出了RxLifecycle,通過細微控制到每一個生命周期函數,更進一步的感知處理每個生命周期函數。
(2)MVVM感知生命周期的方法
創造一個MVVM ViewModel接口 ,里面包含所有的生命周期回掉的方法,然后在Aor f中的各個生命周期函數中調用。
(3)官方的MVVM感知生命周期的方法
在《使用ContentProvider初始化你的Library》 一文中,作者提到使用了ContentProvider進行library的初始化,並通過其控制生命周期函數
LifeCycle 源碼分析:
<provider
android:name = “android.arch.lifecycle.LifecycleRuntimeTrojanProvider"
android:exported = “fasle”
android:multiporcess = “true”
android:authoritites = "com.example.hbl.mbbm.lifecycle-trojan"
/>
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public class LifecycleRuntimeTrojanProviderextends ContentProvider {
@Override
public boolean onCreate() {
LifecycleDispatcher .init ( getContext() ); //初始化生命周期控制的方法
ProcessLifecycleOwner.init( getContext() );
return true;
}
}
在LifecycleDispatcher()方法中 又是如何操作的呢?
Class LifecycleDispatcher{
private static final String REPORT_FRAGMENT_TAG = “android.arch.lifecycle"
+ “.LifecycleDispatcher.report_fragment_tag” ;
private static AtomicBooleansInitialized= new AtomicBoolean ( false);
static void init (Context context) {
if(sInitialized .getAndSet (true) ){
return ;
}else {
( (Application)context .getApplicationContext() ). registerActivityLifecycleCallbacks
(new DispatcherActivityCallback());
}
}
解析:通過AtomicBoolean來控制初始化一次,之后獲取ApplicationContext並設置ActivityLifecycleCallback回調。
ps:AtomicBoolean 函數在退出app的時候可以用到
在DispatcherActivityCallback中:

1、創建了一個FragmentCallback對象,用於設置Fragment的生命周期。
2、在onActivityCreated()函數中 instanceof 一個FragmentActivity,注入一股ReportFragment到當前Activity
3、在ReportFragment中,將這個Fragment 添加到當前Activity中,讓當前的fragment綁定到Activity的生命周期中


5、通過這種方法,給Activity or Fragment添加其他額外的fragment,來獲取當前的Activity 或是Fragment的生命周期。然后判斷當前的Activity 或是Fragment是否是LifeCycleRegistryOwner的。如果是,那么就分發當前的生命周期事件到當前的Owner中,以達到生命周期的傳遞操作
- 官方LifeCycle的使用案例:
(一)創建監聽器
classMyLocationListener{
publicMyLocationListener(Contextcontext,Callbackcallback){
// ...
}
voidstart(){
// connect to system location service
}
voidstop(){
// disconnect from system location service
}
}
在需要的Activity中綁定監聽器
privateMyLocationListenermyLocationListener;
@Override
publicvoidonCreate(...){
myLocationListener =newMyLocationListener(this,(location)->{
// update UI
});
}
@Override
publicvoidonStart(){
super.onStart();
myLocationListener.start();
// manage other components that need to respond
// to the activity lifecycle
}
@Override
publicvoidonStop(){
super.onStop();
myLocationListener.stop();
// manage other components that need to respond
// to the activity lifecycle
}
(二)創建觀察者對象
publicclassMyObserverimplementsLifecycleObserver{
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
publicvoidconnectListener(){
...
}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
publicvoiddisconnectListener(){
...
}
}
myLifecycleOwner.getLifecycle().addObserver(newMyObserver());
(三)實現LifeCycleOwner 綁定Activity或是Fragment生命周期
publicclassMyActivityextendsActivityimplementsLifecycleOwner{
privateLifecycleRegistrymLifecycleRegistry;
@Override
protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
mLifecycleRegistry =newLifecycleRegistry(this);
mLifecycleRegistry.markState(Lifecycle.State.CREATED);
}
@Override
publicvoidonStart(){
super.onStart();
mLifecycleRegistry.markState(Lifecycle.State.STARTED);
}
@NonNull
@Override
publicLifecyclegetLifecycle(){
returnmLifecycleRegistry;
}
}
- 一個有關LifeCycle 的小Ex:
1、定義一個類實現LifeCycleObserver方法
2、定義2個狀態變量
3、自定義類實現LifecycleObserver接口,並添加Lifecycle的生命周期綁定注解
class MyView extends TextView implements LifecycleObserver{
private boolean lifeCycleEnable;
private Lifecycle lifecycle;
//添加構造方法
public boolean isLifeCycleEnable() {
return lifeCycleEnable;
}
public void setLifeCycleEnable(boolean lifeCycleEnable) {
this.lifeCycleEnable = lifeCycleEnable;
}
public Lifecycle getLifecycle() {
return lifecycle;
}
// ****************** lifeCycle 生命周期函數事件******************
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
public void create() {
if (lifeCycleEnable) {
String text = System.currentTimeMillis() + "-create/n";
Log.i(TAG, text);
this.setText(text);
}
}
//同理Lifecycle.Event.ON_其他事件 ON_START 、ON_PAUSE、ON_STOP、ON_RESUME、ON_DESTROY、ON_ANY
}
在Activity中的使用:
publicclass XActivity extends AppCompatActivity implements LifecycleRegistryOwner {
privateLifecycleRegistry lifecycleRegistry =newLifecycleRegistry(this);
//在onCreate()函數中初始化控件 mtx
mtx .setLifecycle(getLifecycle());
//lifecycle觀察者 LifecycleObserver:自定義的類 MyView
//lifecycle注冊擁有者 LifecycleRegistryOwner:XActivity
getLifecycle().addObserver(mtx); //添加觀察者角色
mtx .setLifeCycleEnable(true);
@Override
public LifecycleRegistry getLifecycle() {
return lifecycleRegistry;
}
}
按home鍵進行觀察日志:
creat -> start -> resume -> pause -> stop -> start -> resume
02-24 16:18:31.188 4694-4694/proxy.lifecycledemo E/MyView: Hello World!-creat
02-24 16:18:31.198 4694-4694/proxy.lifecycledemo E/MyView:-start
02-24 16:18:31.198 4694-4694/proxy.lifecycledemo E/MyView:-resume
02-24 16:32:46.058 4694-4694/proxy.lifecycledemo E/MyView:-pause
02-24 16:32:46.798 4694-4694/proxy.lifecycledemo E/MyView:-stop
02-24 16:32:47.988 4694-4694/proxy.lifecycledemo E/MyView:-start
02-24 16:32:47.988 4694-4694/proxy.lifecycledemo E/MyView:-resume
解析:LifecycleOwner是一個只有一個方法的接口getLifecycle(),需要由子類來實現。
在Lib中已經有實現好的子類,我們可以直接拿來使用。比如LifecycleActivity和LifecycleFragment,我們只需要繼承此類就行了。
當然實際開發的時候我們會自己定義BaseActivity,Java是單繼承模式,那么需要自己實現LifecycleRegistryOwner接口。
如下所示即可,代碼很近簡單
public class BaseFragment extends Fragment implements LifecycleRegistryOwner {
LifecycleRegistry lifecycleRegistry = new LifecycleRegistry(this);
@Override
public LifecycleRegistry getLifecycle() {
return lifecycleRegistry;
}
}
Lifecycle的最佳建議
- 保持UI Controllers(Activity/Fragment)中代碼足夠簡潔。一定不能包含如何獲取數據的代碼,要通過ViewModel獲取LiveData形式的數據。
- 用數據驅動UI,UI的職責就是根據數據改變顯示的內容,並且把用戶操作UI的行為傳遞給ViewModel。
- 把業務邏輯相關的代碼放到ViewModel中,把ViewModel看成是鏈接UI和App其他部分的膠水。但ViewModel不能直接獲取數據,要通過調用其他類來獲取數據。
- 使用DataBinding來簡化View(布局文件)和UI Controllers(Activity/Fragment)之間的代碼
- 如果布局本身太過復雜,可以考慮創建一個Presenter類來處理UI相關的改變。雖然這么做會多寫很多代碼,但是對於保持UI的簡介和可測試性是有幫助的。
- 不要在ViewModel中持有任何View/Activity的context。否則會造成內存泄露。
系列文章列表: