Android Architecture Components 系列(二) LifeCycle

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中:
在DispatcherActivityCallback()構造函數中
一、建立了一個FragmentCallback對象,用於設置Fragment的生命週期。
二、在onActivityCreated()函數中 instanceof 一個FragmentActivity,注入一股ReportFragment到當前Activity
三、在ReportFragment中,將這個Fragment 添加到當前Activity中,讓當前的fragment綁定到Activity的生命週期中
 
四、以後經過onActivityCreate()函數中的dispatch()方法把當前生命週期分發到對應的LifecycleOwner中
五、經過這種方法,給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:
    一、定義一個類實現LifeCycleObserver方法 
    二、定義2個狀態變量 
    三、自定義類實現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。不然會形成內存泄露。

 

相關文章
相關標籤/搜索