實現Activity/Fragment生命週期回調的幾種方式

Activity/Fragment的生命週期每個Android的開發人員幾乎每一天都要打交道,其重要性不言而喻。那麼你知道幾種監聽回調的方法呢:直接重寫Activity/Fragment生命週期方法?經過Application#registerActivityLifecycleCallbacks()/FragmentManager#registerFragmentLifecycleCallbacks()註冊回調?實現LifecycleObserver接口?繼承BaseActivity/BaseFragment?方法多多,讓咱們逐條一塊兒展開看看吧! #1.直接重寫Activity/Fragment生命週期方法 這裏展開就有些老生常談了。但仍是有一點值得一提,那就是Android幾乎每個生命週期回調都會要求調用父類方法,若是不調用將會報錯,而檢測是否調用的核心就是Activity.mCalled變量,經過對該變量的判斷,即可知道是否調用了父類方法。固然針對編譯器的檢測,則是經過@CallSuper註解實現的。 ###優勢:可以覆蓋到全部暴露的生命週期方法。 ###缺點:僅能針對本身工程的Activity進行覆寫,擁有必定的侷限性。 #2.registerLifecycleCallbacks ##a.添加Activity回調 Application#registerActivityLifecycleCallbacks()這一API是在API Level 14後添加的。經過該方法,咱們能夠傳遞一個ActivityLifecycleCallbacks的實例,該接口聲明以下:android

public interface ActivityLifecycleCallbacks {
        void onActivityCreated(Activity activity, Bundle savedInstanceState);
        void onActivityStarted(Activity activity);
        void onActivityResumed(Activity activity);
        void onActivityPaused(Activity activity);
        void onActivityStopped(Activity activity);
        void onActivitySaveInstanceState(Activity activity, Bundle outState);
        void onActivityDestroyed(Activity activity);
    }
複製代碼

該方法是一個線程安全的方法,經過該方法添加的監聽器,都存儲在ApplicationmActivityLifecycleCallbacks這一ArrayList中。那麼callbacks的對應方法又是在什麼時候調用的呢?答案就在Activity中。以onActivityCreated()回調爲例:安全

protected void onCreate(@Nullable Bundle savedInstanceState) {
        // ...省略一段代碼
        mFragments.dispatchCreate();
        getApplication().dispatchActivityCreated(this, savedInstanceState);
        if (mVoiceInteractor != null) {
            mVoiceInteractor.attachActivity(this);
        }
        mRestoredFromBundle = savedInstanceState != null;
        mCalled = true;
    }
複製代碼

關鍵就在這一行getApplication().dispatchActivityCreated(this, savedInstanceState);。經過查看源碼咱們發現,Application中一一聲明瞭與ActivityLifecycleCallbacks中方法對應的dispatchActivityXXX()方法,以Application#dispatchActivityCreated()爲例:app

void dispatchActivityCreated(Activity activity, Bundle savedInstanceState) {
        Object[] callbacks = collectActivityLifecycleCallbacks();
        if (callbacks != null) {
            for (int i=0; i<callbacks.length; i++) {
                ((ActivityLifecycleCallbacks)callbacks[i]).onActivityCreated(activity,
                        savedInstanceState);
            }
        }
    }
複製代碼

Application會遍歷這一時刻添加的全部ActivityLifecycleCallbacks並回調對應的生命週期方法。同時咱們也發現,這一方式沒法作到在Activity的聲明週期調用以前作一些事情,由於回調生在在supert.onXXX()中。 ##b.添加Fragment回調 FragmentManager#registerFragmentlifecyclecallbacks()這一API是在support library version 25.1.0中添加的。咱們能夠經過傳遞一個``類的實現類以及一個boolean類型的變量來實現生命週期的監聽,該抽象類聲明以下:框架

public abstract static class FragmentLifecycleCallbacks {

        public void onFragmentPreAttached(@NonNull FragmentManager fm, @NonNull Fragment f, @NonNull Context context) {}

        public void onFragmentAttached(@NonNull FragmentManager fm, @NonNull Fragment f, @NonNull Context context) {}

        public void onFragmentPreCreated(@NonNull FragmentManager fm, @NonNull Fragment f, @Nullable Bundle savedInstanceState) {}

        public void onFragmentCreated(@NonNull FragmentManager fm, @NonNull Fragment f, @Nullable Bundle savedInstanceState) {}

        public void onFragmentActivityCreated(@NonNull FragmentManager fm, @NonNull Fragment f, @Nullable Bundle savedInstanceState) {}

        public void onFragmentViewCreated(@NonNull FragmentManager fm, @NonNull Fragment f, @NonNull View v, @Nullable Bundle savedInstanceState) {}

        public void onFragmentStarted(@NonNull FragmentManager fm, @NonNull Fragment f) {}

        public void onFragmentResumed(@NonNull FragmentManager fm, @NonNull Fragment f) {}

        public void onFragmentPaused(@NonNull FragmentManager fm, @NonNull Fragment f) {}

        public void onFragmentStopped(@NonNull FragmentManager fm, @NonNull Fragment f) {}

        public void onFragmentSaveInstanceState(@NonNull FragmentManager fm, @NonNull Fragment f, @NonNull Bundle outState) {}

        public void onFragmentViewDestroyed(@NonNull FragmentManager fm, @NonNull Fragment f) {}

        public void onFragmentDestroyed(@NonNull FragmentManager fm, @NonNull Fragment f) {}

        public void onFragmentDetached(@NonNull FragmentManager fm, @NonNull Fragment f) {}
    }
複製代碼

值得注意的是,相比Application的方法相比,FragmentManager的方法多了一個參數:boolean recursive,若是該參數爲true,則會爲全部子孫Fragment也註冊回調。 首先,Fragment的生命週期由FragmentManager經過moveToState()方法調用。一樣,這裏以onFragmentCreated爲例,其調用流程以下: moveToState() -> dispatchOnFragmentCreated(),dispatchOnFragmentCreated()代碼:ide

void dispatchOnFragmentCreated(@NonNull Fragment f, @Nullable Bundle savedInstanceState, boolean onlyRecursive) {
        // ...省略一段代碼
        // 遍歷callback回調聲明週期方法
        for (FragmentLifecycleCallbacksHolder holder : mLifecycleCallbacks) {
            if (!onlyRecursive || holder.mRecursive) {
                holder.mCallback.onFragmentCreated(this, f, savedInstanceState);
            }
        }
    }
複製代碼

到這裏咱們能夠發現,與ActivityLifecycleCallbacks同樣,這一方式一樣在onXXX()方法以後進行。 綜上所屬,這種方式的優缺點以下: ###優勢:函數

  • 能夠統一監聽全部Activity/Fragment,方便管理。
  • 不侵入已有代碼,耦合性較低。
  • 並且能夠操做第三方Activity/Fragment的聲明週期。 ###缺點:僅能在相應週期回調後操做,是這一方法惟一的缺點。 #3.BaseActivity/BaseFragment 這一方法就是實現一個基類Activity/Fragment,在裏面實現一些通用的方法,讓項目中的activity都繼承它,來達到封裝的目的。可是該方法缺點也很明顯,因爲Java的繼承機制只容許一個類擁有惟一父類,因此該方法沒法用於第三方框架也使用該方式的場景,而且侵入性強。 #4.實現LifecycleObserver 該方法是支持庫中的類,現已嵌入androidX包中。該接口聲明以下:
public interface LifecycleObserver {}
複製代碼

能夠看到,這就是一個空接口,他的意義就是標記類,由於僅僅實現該方法並不能監控任何生命週期回調。爲了監控生命週期,咱們還須要配合@OnLifecycleEvent註解一同食用:post

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface OnLifecycleEvent {
    Lifecycle.Event value();
}
複製代碼

該註解接收一個Lifecycle.Event類型的參數,這是一個枚舉類,聲明瞭能夠監控到的生命週期變動事件:this

public enum Event {
        ON_CREATE,
        ON_START,
        ON_RESUME,
        ON_PAUSE,
        ON_STOP,
        ON_DESTROY,
        ON_ANY
    }
複製代碼

其中值得說明的是ON_ANY,該值表示任何變動事件都將回調。完整的例子以下:spa

class LifecycleListener: LifecycleObserver {

    @OnLifecycleEvent(Lifecycle.Event.ON_ANY)
    fun onStateChanged(owner:LifecycleOwner,event:Lifecycle.Event){
        Log.e("LifecycleListener","owner $owner,event $event")
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_ANY)
    fun onStateChanged(owner:LifecycleOwner){
        Log.e("LifecycleListener","owner $owner")
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_ANY)
    fun onStateChanged(){
        Log.e("LifecycleListener","called")
    }

}
複製代碼

須要注意兩點:線程

  • 實現LifecycleObserver的類,必須擁有一個無參的構造函數;
  • @OnLifecycleEvent註解的方法,參數能夠有0-2個,其中1-2的參數類型,必須按如上聲明,不然會報錯(由於系統只會按照上述順序傳參) 接下來還有最後一步:註冊觀察者!
class TestActivity : BaseActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 添加Observer
        lifecycle.addObserver(LifecycleListener())
    }
}
複製代碼

###ps:FragmentActivity使用方式相同 這一步是經過調用Lifecycle#addObserver()實現的,對於ComponentActivity而言,實際調用的是LifecycleRegistry#addObserver()方法。 ##優勢:

  • 侵入性低
  • 使用靈活 ##缺點:
  • 可監控生命週期種類較少
  • 沒法對第三方Activity/Fragment直接使用 下面讓咱們來分析一下,這一方式是如何實現的! Lifecycle組件的實現原理
相關文章
相關標籤/搜索