Android Jetpack組件之Lifecycles庫詳解


Android Jetpack 組件是庫的集合,這些庫是為了協同工作而構建的,不過也可以單獨采用,接下來會一一詳細地學習這些庫, 下面源碼版本是com.android.support:appcompat-v7:28.0.0, 以及庫android.arch.lifecycle:extensions:1.1.1

Lifecycles庫是拿來干什么的

這個庫從系統框架層去管理具有生命周期的組件,例如activity, fragment。讓開發更方便地去管理自己應用里需要和activity或者fragment綁定的組件,讓代碼更容易維護。

也許有點抽象,舉個例子說明一下,比如有個需求,需要在一個界面比較頻繁更新地理位置信息。當Activity走了onstop之后,你應該也要暫停更新地理位置,或者當Activity走destroy后,你要釋放一些資源。下面用一些代碼實例解析一下,你的代碼也許是這樣的:

class MyLocationListener { public MyLocationListener(Context context, Callback callback) { // ... } void start() { // 開始連接位置服務 } void stop() { // 停止連接位置服務 } void destroy(){ //釋放資源 } } class MyActivity extends AppCompatActivity { private MyLocationListener myLocationListener; @Override public void onCreate(...) { myLocationListener = new MyLocationListener(this, new Callback(){ //回調更新UI }); } @Override public void onStart() { super.onStart(); myLocationListener.start(); //綁定actiivty的onStart周期函數 } @Override public void onStop() { super.onStop(); myLocationListener.stop(); //綁定actiivty的onStop周期函數 } @Override public void onDestroy() { super.onDestroy(); myLocationListener.destroy(); //綁定actiivty的onDestroy周期函數 } } 復制代碼

上面的代碼在簡單app看起來也許還好,但是當你activity業務邏輯比較多,可能包含很多和生命周期綁定的自定義組件,代碼長期積累就很難維護啦。

下面在看看使用Lifecycles庫的代碼做對比:

class MyLocationListener implements LifecycleObserver{ public MyLocationListener(Context context, Callback callback) { // ... } @OnLifecycleEvent(Lifecycle.Event.ON_START) void start() { // 開始連接位置服務 } @OnLifecycleEvent(Lifecycle.Event.ON_STOP) void stop() { // 停止連接位置服務 } @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) void destroy(){ //釋放資源 } } class MyActivity extends AppCompatActivity { private MyLocationListener myLocationListener; @Override public void onCreate(...) { myLocationListener = new MyLocationListener(this, new Callback(){ //回調更新UI }); getLifecycle().addObserver(myLocationListener); } } 復制代碼

MyLocationListener實現LifecycleObserver, 在相應的方法添加OnLifecycleEvent注解就可以收到相應的回調,在Activity的onCreate方法里調用 getLifecycle().addObserver(myLocationListener)即可。下面結合源碼分析Lifecycles庫, 去更好地學習這個庫。

Lifecycles庫核心類與結構

Support Library 26.1.0 版本以及之后的版本,AppCompatActivity和Fragment實現了LifecycleOwner。類圖如下所示:

jetpack_lifecycle_01

Lifecycles庫核心就是訂閱者模式。

LifecycleOberver類:只是個空接口, 安卓生命周期觀察者,

Lifecycle類: 是個抽象類,定義了安卓生命周期對象,有3個方法,添加觀察者,移除觀察者,獲取當前狀態。

LifecycleOwner類: 是個接口, 安卓生命周期的擁有者

LifecycleRegistry: Lifecycle的實現類,實現了添加、移除觀察者,分派觀察者狀態等

自定義類實現LifecycleOberver接口,在方法中添加OnLifecycleEvent注解就可以收到相應生命周期的狀態

public @interface OnLifecycleEvent {
    Lifecycle.Event value();
}

public enum Event { 
    ON_CREATE,
    ON_START,
    ON_RESUME,
    ON_PAUSE,
    ON_STOP,
    ON_DESTROY,
    ON_ANY
}
//Event是Lifecycle內部類一個枚舉類, 分別定義了onCreate, onStart, onResume, onPause,onStop,onDestroy, onAny這幾個Event

public enum State {
    DESTROYED,
    INITIALIZED,
    CREATED,
    STARTED,
    RESUMED;

    public boolean isAtLeast(@NonNull State state) {
    	return compareTo(state) >= 0; } }//State也是Lifecycle內部類一個枚舉類, 定義了INITIALIZED, CREATED, STARTED, RESUMED, DESTROYED幾種狀態 復制代碼

Lifecycle的各個狀態以及事件分發過程如下圖所示: (該圖來自google官網文檔)


矩形代表狀態,一共有5個狀態,記錄在枚舉State中, 依次是DESTROYED, INITIALIZED, CREATED, STARTED, RESUMED;

箭頭上面代表分發的Event:

  • 當分發ON_CREATE事件時,State由INITIALIZED -> CREATED;
  • 當分發ON_START事件時, State由CREATED -> STARTED
  • 當分發ON_RESUME事件時, State由STARTED -> RESUMED
  • 當分發ON_PAUSE事件時, State由RESUMED -> STARTED
  • 當分發ON_STOP事件時, State由STARTED -> CREATED
  • 當分發ON_DESTROY事件時, State由CREATED -> DESTROYED

你會發現State沒STOPED和PAUSED的狀態, 當State=CREATED時, Activity大概是在onCreate調用后或者onStop調用后;當State=STARTED時, Activity大概是在onStart調用后或者onPause調用后

ComponentActivity分發Event的過程

下面截取部分ComponentActivity的關鍵代碼

public class ComponentActivity extends Activity implements LifecycleOwner{ private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this); protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); ReportFragment.injectIfNeededIn(this); //利用Fragment來分發 } @CallSuper @Override protected void onSaveInstanceState(Bundle outState) { mLifecycleRegistry.markState(Lifecycle.State.CREATED); //onSaveInstanceState是用來恢復Activity狀態的, 這里記錄的狀態是CREATED super.onSaveInstanceState(outState); } @Override public Lifecycle getLifecycle() { return mLifecycleRegistry; //返回LifecycleRegistry } } 復制代碼

下面再看ReportFragment類關鍵代碼:

    public static void injectIfNeededIn(Activity activity) { // 為當前activity add 一個ReportFragment,用於分發event android.app.FragmentManager manager = activity.getFragmentManager(); if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) { manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit(); manager.executePendingTransactions(); } } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); dispatch(Lifecycle.Event.ON_CREATE); //分發ON_CREATE Event } @Override public void onStart() { super.onStart(); dispatch(Lifecycle.Event.ON_START);//分發ON_START Event } @Override public void onResume() { super.onResume(); dispatch(Lifecycle.Event.ON_RESUME);//分發ON_RESUME Event } @Override public void onPause() { super.onPause(); dispatch(Lifecycle.Event.ON_PAUSE);//分發ON_PAUSE Event } @Override public void onStop() { super.onStop(); dispatch(Lifecycle.Event.ON_STOP);//分發ON_STOP Event } @Override public void onDestroy() { super.onDestroy(); dispatch(Lifecycle.Event.ON_DESTROY);//分發ON_DESTROY Event } private void dispatch(Lifecycle.Event event) { Activity activity = getActivity(); // Activity是實現LifecycleOwner接口,這里可以跳過 if (activity instanceof LifecycleRegistryOwner) { ((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event); return; } if (activity instanceof LifecycleOwner) { Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle(); if (lifecycle instanceof LifecycleRegistry) { ((LifecycleRegistry) lifecycle).handleLifecycleEvent(event); //最終調用LifecycleRegistry.handleLifecycleEvent(event)處理event分發 } } } 復制代碼

ComponentActivity的是Event分發是通過添加一個ReportFragment, 通過重寫ReportFragment的onActivityCreated, onStart, onResume, onStop, onPause, onDestroy方法,最終交給LifecycleRegistry.handleLifecycleEvent(event)處理。

Fragment分發Event的過程

下面也是截去相關v4里Fragment的相關源碼

    LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this); @Override public Lifecycle getLifecycle() { return mLifecycleRegistry; } void performCreate(Bundle savedInstanceState) { ... onCreate(savedInstanceState); ... mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE); } void performStart() { ... onStart(); ... mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START); } void performResume() { ... onResume(); ... mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME); } void performPause() { mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE); ... onPause(); ... } void performStop() { mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP); ... onStop(); ... } void performDestroy() { mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY); ... onDestroy(); ... } 復制代碼

LifecycleRegistry.handleLifecycleEvent(event)處理。 至於LifecycleRegistry這個類更多的細節就不展開啦

自定義LifecycleOwner

前面提到Support Library 26.1.0 版本以及之后的版本,AppCompatActivity和Fragment實現了LifecycleOwner, 如果你還用舊的版本或者繼承Activity, 你可以通過自定義Activity或者Fragment實現。自定義實現代碼如下:

//可以單獨引入androidx.lifecycle:lifecycle-runtime:$lifecycle_version庫 public class MyActivity extends Activity implements LifecycleOwner { private LifecycleRegistry mLifecycleRegistry; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mLifecycleRegistry = new LifecycleRegistry(this); mLifecycleRegistry.markState(Lifecycle.State.CREATED); } @Override public void onStart() { super.onStart(); mLifecycleRegistry.markState(Lifecycle.State.STARTED); } .... @NonNull @Override public Lifecycle getLifecycle() { return mLifecycleRegistry; } } 復制代碼

使用ProcessLifecycleOwner監聽整個App進程的前后台

要注意ON_CREATE的Event之后分發一次,ON_DESTROY不會分發

public class App extends Application { @Override public void onCreate() { super.onCreate(); ProcessLifecycleOwner.get().getLifecycle().addObserver(new LifecycleObserver() { private static final String TAG = "ProcessLifecycleOwner"; @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) public void onCreate(){ Log.d(TAG, "onCreate: "); //應用啟動只被調用一次 } @OnLifecycleEvent(Lifecycle.Event.ON_START) public void onStart(){ Log.d(TAG, "onStart: "); //應用啟動會調用一次, 從后台回來也會調用 } @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) public void onResume(){ Log.d(TAG, "onResume: "); //應用啟動會調用一次, 從后台回來也會調用 } @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) public void onPause(){ Log.d(TAG, "onPause: "); //按home鍵或者切換應用會調用 } @OnLifecycleEvent(Lifecycle.Event.ON_STOP) public void onStop(){ Log.d(TAG, "onStop: "); //按home鍵或者切換應用會調用 } }); } 復制代碼

要注意ON_PAUSE, ON_STOP的回調會有700毫秒的延遲, 官方的解析是保證不要由於配置更改而銷毀和重新Activity時不會分發任何事件。還有一點,如果你的app是多進程應用,ProcessLifecycleOwner只能用來監聽主進程。

更多細節參考:developer.android.google.cn/reference/a…

下面簡單說一下ProcessLifecycleOwner的工作原理:

// ProcessLifecycleOwner 關鍵代碼 public class ProcessLifecycleOwner implements LifecycleOwner{ private int mStartedCounter = 0; // 計數器 private int mResumedCounter = 0; // 計數器 void activityResumed() { mResumedCounter++; if (mResumedCounter == 1) { if (mPauseSent) { mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME); mPauseSent = false; } else { mHandler.removeCallbacks(mDelayedPauseRunnable); } } } void activityPaused() { mResumedCounter--; if (mResumedCounter == 0) { mHandler.postDelayed(mDelayedPauseRunnable, TIMEOUT_MS); } } void attach(Context context) { mHandler = new Handler(); //mRegistry是LifecycleRegistry對象,依靠LifecycleRegistry分發Event,不多說 mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE); Application app = (Application) context.getApplicationContext(); //利用registerActivityLifecycleCallbacks注冊callback監聽activity生命周期 //細看activityResumed和activityPaused方法,通過Activity計數法來實現應用前后台的監聽 app.registerActivityLifecycleCallbacks(new EmptyActivityLifecycleCallbacks() { @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) { ReportFragment.get(activity).setProcessListener(mInitializationListener); } @Override public void onActivityPaused(Activity activity) { activityPaused(); } @Override public void onActivityStopped(Activity activity) { activityStopped(); } }); } static void init(Context context) { // 初始化 sInstance.attach(context); } } public class ProcessLifecycleOwnerInitializer extends ContentProvider { @Override public boolean onCreate() { LifecycleDispatcher.init(getContext()); //這是個ContentProvider,在onCreate方法初始化ProcessLifecycleOwner //主進程的第一個ContentProvider.onCreate是比Application.onCreate先調用的 //這個ContentProvider會注冊在Androidmenifest中,從而不用再Application中進行ProcessLifecycleOwner初始化 ProcessLifecycleOwner.init(getContext()); return true; } } 復制代碼

LifecycleService的使用

LifecycleService 繼承Service, 並實現LifecycleOwner, 可以自定義一個服務繼承LifecycleService來使用,下面是代碼實例:

public class MyService extends LifecycleService {

    public MyService() {
    }

    @Override
    public void onCreate() {
        super.onCreate();
        getLifecycle().addObserver(new LifecycleObserver() {

            @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
            public void onCreate(){
                Log.d(TAG, "onCreate: ");
            }

            @OnLifecycleEvent(Lifecycle.Event.ON_START)
            public void onStart(){
                Log.d(TAG, "onStart: ");
            }

            @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
            public void onStop(){
                Log.d(TAG, "onStop: ");
            }
            
            @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
            public void onDestroy(){
                Log.d(TAG, "onDestroy: ");
            }

        });
    }
}
復制代碼

總結以及其他的Tips

Lifecycles庫為Jetpack其他組件打下了基礎,通過LifecycleObserver觀察者減少對Activity, Fragment, 和Service這些具有生命周期類的依賴。

  • 是使用LifecycleService和ProcessLifecycleOwner需要引入android.arch.lifecycle:extensions:1.1.1庫,它並沒有包含在com.android.support:appcompat-v7:version中
  • 在使用到Lifecycles庫時最好在gradle引入apt編譯器庫annotationProcessor "android.arch.lifecycle:compiler:1.1.1", 沒引入這庫,對應注解@OnLifecycleEvent的方法就是使用反射來實現的,當引入這庫后,會在編譯時期自動生成YourObserverName_LifecycleAdapter類實現0反射提高性能。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM