Android 關於監控生命週期的幾種策略

上面文章講了 Android Support Library 26.1.0 開始,引入Lifecycles。官方正式完善了 Activity、Fragment 生命週期監控這方面的代碼。

 

在這之前我有看到這麼兩種方案。

第一種是 Glide 使用的方案。

以上是Glide 的簡單用法是這樣的。

 

1、如何實現綁定生命週期

public class Glide implements ComponentCallbacks2 {

  public static RequestManager with(@NonNull Activity activity) {
    return getRetriever(activity).get(activity);
  }

  public static RequestManager with(@NonNull FragmentActivity activity) {
    return getRetriever(activity).get(activity);
  }

  public static RequestManager with(@NonNull Fragment fragment) {
    return getRetriever(fragment.getActivity()).get(fragment);
  }

  public static RequestManager with(@NonNull android.app.Fragment fragment) {
    return getRetriever(fragment.getActivity()).get(fragment);
  }

Glide.with 方法可以傳入不同的參數,上面這4個方法都會先通過 getRetriever 方法獲取到 RequestManagerRetriever。

RequestManagerRetriever 是一個  RequestManager 的容器。用來新建&緩存 RequestManager 實體。

這裏拿參數是 Activity 的方法來舉例。 

getRetriever(activity).get(activity);  前半句 getRetriever(activity) 是獲取 Glide 類的屬性 requestManagerRetriever。

後半句是獲取一個 RequestManager。展開裏面的詳細代碼如下:

RequestManagerRetriever.java
——————————————————————————————
public class RequestManagerRetriever implements Handler.Callback {

  public RequestManager get(@NonNull Activity activity) {
    if (Util.isOnBackgroundThread()) {
      return get(activity.getApplicationContext());
    } else {
      assertNotDestroyed(activity);
      android.app.FragmentManager fm = activity.getFragmentManager();
      return fragmentGet(
          activity, fm, /*parentHint=*/ null, isActivityVisible(activity));
    }
  }

  private RequestManager fragmentGet(@NonNull Context context,
      @NonNull android.app.FragmentManager fm,
      @Nullable android.app.Fragment parentHint,
      boolean isParentVisible) {
    RequestManagerFragment current = getRequestManagerFragment(fm, parentHint, isParentVisible);
    RequestManager requestManager = current.getRequestManager();
    if (requestManager == null) {
      // TODO(b/27524013): Factor out this Glide.get() call.
      Glide glide = Glide.get(context);
      requestManager =
          factory.build(
              glide, current.getGlideLifecycle(), current.getRequestManagerTreeNode(), context);
      current.setRequestManager(requestManager);
    }
    return requestManager;
  }

  private RequestManagerFragment getRequestManagerFragment(
      @NonNull final android.app.FragmentManager fm,
      @Nullable android.app.Fragment parentHint,
      boolean isParentVisible) {
    RequestManagerFragment current = (RequestManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
    if (current == null) {
      current = pendingRequestManagerFragments.get(fm);
      if (current == null) {
        current = new RequestManagerFragment();
        current.setParentFragmentHint(parentHint);
        if (isParentVisible) {
          current.getGlideLifecycle().onStart();
        }
        pendingRequestManagerFragments.put(fm, current);
        fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
        handler.obtainMessage(ID_REMOVE_FRAGMENT_MANAGER, fm).sendToTarget();
      }
    }
    return current;
  }





RequestManagerFragment.java
——————————————————————————————
public class RequestManagerFragment extends Fragment {

  private final ActivityFragmentLifecycle lifecycle;

  public RequestManagerFragment() {
    this(new ActivityFragmentLifecycle());
  }

  @VisibleForTesting
  @SuppressLint("ValidFragment")
  RequestManagerFragment(@NonNull ActivityFragmentLifecycle lifecycle) {
    this.lifecycle = lifecycle;
  }

由於新建一個 RequestManager 需要一個「生命週期實體 Lifecycle」的傳參。

什麼東西可以獲取到生命週期呢,Activity裏已經無法插入代碼,還有其他辦法嗎?

如果瞭解我上篇文章《Android LiveData我的理解》,可以猜到 Glide 也是要利用了爲 Activity 裏面添加無UI的Fragment這招了。事實上這招應該 Glide 先發現的。

Glide 爲這套流程編寫了一個 Fragment 的子類 RequestManagerFragment,創建 RequestManagerFragment 的構造方法會創建一個 ActivityFragmentLifecycle。最終實現 RequestManager 和 這個 RequestManagerFragment 裏面的 ActivityFragmentLifecycle 綁定。 RequestManager 就獲得了一個「生命週期實體 Lifecycle」的傳參了。

上面這段代碼就是這段邏輯的實現,其中還有一個細節是 RequestManagerFragment 會嘗試從緩存中獲取。

 

RequestManager 是利用工廠模式, factory.build 方法創建的,其中傳入最重要的參數 RequestManagerFragment 裏面的 lifecycle。它的構造方法如下:

public class RequestManager implements LifecycleListener,
    ModelTypes<RequestBuilder<Drawable>> {

  final Lifecycle lifecycle;

  private final Runnable addSelfToLifecycle = new Runnable() {
    @Override
    public void run() {
      lifecycle.addListener(RequestManager.this);
    }
  };

  RequestManager(
      Glide glide,
      Lifecycle lifecycle,
      RequestManagerTreeNode treeNode,
      RequestTracker requestTracker,
      ConnectivityMonitorFactory factory,
      Context context) {
    this.glide = glide;
    this.lifecycle = lifecycle;
    this.treeNode = treeNode;
    this.requestTracker = requestTracker;
    this.context = context;

    connectivityMonitor =
        factory.build(
            context.getApplicationContext(),
            new RequestManagerConnectivityListener(requestTracker));

    // If we're the application level request manager, we may be created on a background thread.
    // In that case we cannot risk synchronously pausing or resuming requests, so we hack around the
    // issue by delaying adding ourselves as a lifecycle listener by posting to the main thread.
    // This should be entirely safe.
    if (Util.isOnBackgroundThread()) {
      mainHandler.post(addSelfToLifecycle);
    } else {
      lifecycle.addListener(this);
    }
    lifecycle.addListener(connectivityMonitor);

    defaultRequestListeners =
        new CopyOnWriteArrayList<>(glide.getGlideContext().getDefaultRequestListeners());
    setRequestOptions(glide.getGlideContext().getDefaultRequestOptions());

    glide.registerRequestManager(this);
  }

在 RequestManager 的構造方法中,會執行 lifecycle.addListener(this); 把當前 RequestManager 添加到 lifecycle 的觀察者列表裏。

 

2、如何接受生命週期事件

在 RequestManagerFragment 中,重寫了 onStart、onStop、onDestroy 方法。Activity

RequestManagerFragment.java
——————————————————————————————
public class RequestManagerFragment extends Fragment {

  @Override
  public void onStart() {
    super.onStart();
    lifecycle.onStart();
  }

  @Override
  public void onStop() {
    super.onStop();
    lifecycle.onStop();
  }

  @Override
  public void onDestroy() {
    super.onDestroy();
    lifecycle.onDestroy();
    unregisterFragmentWithRoot();
  }




ActivityFragmentLifecycle.java
——————————————————————————————
class ActivityFragmentLifecycle implements Lifecycle {

  void onStart() {
    isStarted = true;
    for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
      lifecycleListener.onStart();
    }
  }

  void onStop() {
    isStarted = false;
    for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
      lifecycleListener.onStop();
    }
  }

  void onDestroy() {
    isDestroyed = true;
    for (LifecycleListener lifecycleListener : Util.getSnapshot(lifecycleListeners)) {
      lifecycleListener.onDestroy();
    }
  }



RequestManager.java
——————————————————————————————
public class RequestManager implements LifecycleListener,
    ModelTypes<RequestBuilder<Drawable>> {
  @Override
  public synchronized void onStart() {
    resumeRequests();
    targetTracker.onStart();
  }


  @Override
  public synchronized void onStop() {
    pauseRequests();
    targetTracker.onStop();
  }


  @Override
  public synchronized void onDestroy() {
    targetTracker.onDestroy();
    for (Target<?> target : targetTracker.getAll()) {
      clear(target);
    }
    targetTracker.clear();
    requestTracker.clearRequests();
    lifecycle.removeListener(this);
    lifecycle.removeListener(connectivityMonitor);
    mainHandler.removeCallbacks(addSelfToLifecycle);
    glide.unregisterRequestManager(this);
  }

這3個方法裏會調用到 lifecycle 的方法,lifecycle會遍歷自身的 lifecycleListeners,執行對應方法。因爲 RequestManager 剛纔添加監聽時候傳入了自己,也實現了 LifecycleListener 接口,所以最終回調到這裏的 onStart、onStop、onDestroy 方法。比如 onDestroy 就就會去取消加載圖片任務,釋放相應資源,把自己從生命週期監聽集合中移除。


ps:RequestManager、ActivityFragmentLifecycle 和 RequestManagerFragment 這3者是1對1對1的關係。一個 RequestManager 管理着這個頁面(Activity/Fragment)下的所有圖片加載任務。當這個頁面(Activity/Fragment)銷燬了,對應的 RequestManagerFragment 也銷燬了,對應的 RequestManager 的所有任務也應該取消掉+資源釋放掉。

 

 

第二種是 MVPArms 使用的方案。

MVPArms 是一個 Android MVP 快速集成框架,裏面用到 RxLifecycle 庫。

RxLifecycle 作用是可以根據生命週期發送的事件,自動釋放(dispose) Rxjava2 的訂閱。

免除你手寫 dispose 代碼,可以防止內存泄露的情況發生。

1、 Activity & Fragment 全局性的生命週期回調

Application.java
——————————————————————————————
public class Application extends ContextWrapper implements ComponentCallbacks2 {
    public void registerActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback) {
        synchronized (mActivityLifecycleCallbacks) {
            mActivityLifecycleCallbacks.add(callback);
        }
    }


    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);
    }

FragmentManager.java
——————————————————————————————
public abstract class FragmentManager {

    public abstract void registerFragmentLifecycleCallbacks(@NonNull FragmentManager.FragmentLifecycleCallbacks var1, boolean var2);

    public abstract static class FragmentLifecycleCallbacks {
        public 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) {}
    }

FragmentManagerImpl.java
——————————————————————————————
final class FragmentManagerImpl extends FragmentManager implements Factory2 {

    public void registerFragmentLifecycleCallbacks(FragmentLifecycleCallbacks cb, boolean recursive) {
        this.mLifecycleCallbacks.add(new FragmentManagerImpl.FragmentLifecycleCallbacksHolder(cb, recursive));
    }

在 Application 裏使用 registerActivityLifecycleCallbacks 註冊 Actiivity 的生命週期回調估計大家都知道了。Fragment 也有相應的註冊生命週期回調的方法,是在 FragmentManager 裏使用 registerFragmentLifecycleCallbacks。

提示到這步應該很好猜到下面怎麼實現了。就是在這麼 Activity/Fragment 的 callback 方法裏插入發送生命週期事件的代碼。

 

2、Activity 的生命週期註冊

需要先講解一下 RxLifecycle 的原理。大概可以理解爲,RxJava 像是上游發送數據給下游,正常流程「下游Observer」 在 Activity/Fragment 銷燬後應該跟着銷燬+釋放資源。

RxLifecycle 的原理是讓 「下游Observer」可以接收另一個上游事件,在這裏是生命週期事件,比如設定接收到 onDestroy 事件就把這個 RxJava 流銷燬+釋放資源。

Lifecycleable.java
——————————————————————————————
public interface Lifecycleable<E> {
    @NonNull
    Subject<E> provideLifecycleSubject();
}


ActivityLifecycleable.java
——————————————————————————————
public interface ActivityLifecycleable extends Lifecycleable<ActivityEvent> {
}


FragmentLifecycleable.java
——————————————————————————————
public interface FragmentLifecycleable extends Lifecycleable<FragmentEvent> {
}


BaseActivity.java
——————————————————————————————
public abstract class BaseActivity<P extends IPresenter> extends AppCompatActivity implements IActivity, ActivityLifecycleable {

    private final BehaviorSubject<ActivityEvent> mLifecycleSubject = BehaviorSubject.create();

    @NonNull
    @Override
    public final Subject<ActivityEvent> provideLifecycleSubject() {
        return mLifecycleSubject;
    }



BaseFragment.java
——————————————————————————————
public abstract class BaseFragment<P extends IPresenter> extends Fragment implements IFragment, FragmentLifecycleable {

    private final BehaviorSubject<FragmentEvent> mLifecycleSubject = BehaviorSubject.create();

    @NonNull
    @Override
    public final Subject<FragmentEvent> provideLifecycleSubject() {
        return mLifecycleSubject;
    }

MVPArms 中在 BaseActivity 和 BaseFragment 就實現了一個 Lifecycleable 接口,提供出來了一個獲取 Subject 的方法。這裏Subject 可以暫時理解爲一個上游事件發射器。

下面來看看實現了 Application.ActivityLifecycleCallbacks 的子類,這個子類會在 application 中調用 register 方法進行註冊。

ActivityLifecycleForRxLifecycle.java
——————————————————————————————
public class ActivityLifecycleForRxLifecycle implements Application.ActivityLifecycleCallbacks {
    @Inject
    Lazy<FragmentLifecycleForRxLifecycle> mFragmentLifecycle;

    @Inject
    public ActivityLifecycleForRxLifecycle() {
    }

    /**
     * 通過橋樑對象 {@code BehaviorSubject<ActivityEvent> mLifecycleSubject}
     * 在每個 Activity 的生命週期中發出對應的生命週期事件
     */
    @Override
    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
        if (activity instanceof ActivityLifecycleable) {
            obtainSubject(activity).onNext(ActivityEvent.CREATE);
            if (activity instanceof FragmentActivity) {
                ((FragmentActivity) activity).getSupportFragmentManager().registerFragmentLifecycleCallbacks(mFragmentLifecycle.get(), true);
            }
        }
    }

    @Override
    public void onActivityStarted(Activity activity) {
        if (activity instanceof ActivityLifecycleable) {
            obtainSubject(activity).onNext(ActivityEvent.START);
        }
    }

    @Override
    public void onActivityResumed(Activity activity) {
        if (activity instanceof ActivityLifecycleable) {
            obtainSubject(activity).onNext(ActivityEvent.RESUME);
        }
    }

    @Override
    public void onActivityPaused(Activity activity) {
        if (activity instanceof ActivityLifecycleable) {
            obtainSubject(activity).onNext(ActivityEvent.PAUSE);
        }
    }

    @Override
    public void onActivityStopped(Activity activity) {
        if (activity instanceof ActivityLifecycleable) {
            obtainSubject(activity).onNext(ActivityEvent.STOP);
        }
    }

    @Override
    public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

    }

    @Override
    public void onActivityDestroyed(Activity activity) {
        if (activity instanceof ActivityLifecycleable) {
            obtainSubject(activity).onNext(ActivityEvent.DESTROY);
        }
    }

    /**
     * 從 {@link com.jess.arms.base.BaseActivity} 中獲得橋樑對象 {@code BehaviorSubject<ActivityEvent> mLifecycleSubject}
     *
     * @see <a href="https://mcxiaoke.gitbooks.io/rxdocs/content/Subject.html">BehaviorSubject 官方中文文檔</a>
     */
    private Subject<ActivityEvent> obtainSubject(Activity activity) {
        return ((ActivityLifecycleable) activity).provideLifecycleSubject();
    }
}

各個生命週期的回調方法會把 activity 實體當做參數傳過來,所以根據這個 activity 判斷+強轉成 ActivityLifecycleable,然後獲取到 生命週期的上游事件發射器 Subject,發送一個生命週期事件出去。

注意在 onActivityCreated 方法中,判斷 instanceof FragmentActivity,然後會註冊 Fragment 生命週期的回調。

因爲涉及到 dagger2 的使用,在這裏不是重點所以省略了。mFragmentLifecycle.get() 在這裏返回的是一個 FragmentLifecycleForRxLifecycle 實例,下面是 FragmentManager.FragmentLifecycleCallbacks 的子類實現。

@Singleton
public class FragmentLifecycleForRxLifecycle extends FragmentManager.FragmentLifecycleCallbacks {

    @Inject
    public FragmentLifecycleForRxLifecycle() {
    }

    @Override
    public void onFragmentAttached(FragmentManager fm, Fragment f, Context context) {
        if (f instanceof FragmentLifecycleable) {
            obtainSubject(f).onNext(FragmentEvent.ATTACH);
        }
    }

    @Override
    public void onFragmentCreated(FragmentManager fm, Fragment f, Bundle savedInstanceState) {
        if (f instanceof FragmentLifecycleable) {
            obtainSubject(f).onNext(FragmentEvent.CREATE);
        }
    }

    @Override
    public void onFragmentViewCreated(FragmentManager fm, Fragment f, View v, Bundle savedInstanceState) {
        if (f instanceof FragmentLifecycleable) {
            obtainSubject(f).onNext(FragmentEvent.CREATE_VIEW);
        }
    }

    @Override
    public void onFragmentStarted(FragmentManager fm, Fragment f) {
        if (f instanceof FragmentLifecycleable) {
            obtainSubject(f).onNext(FragmentEvent.START);
        }
    }

    @Override
    public void onFragmentResumed(FragmentManager fm, Fragment f) {
        if (f instanceof FragmentLifecycleable) {
            obtainSubject(f).onNext(FragmentEvent.RESUME);
        }
    }

    @Override
    public void onFragmentPaused(FragmentManager fm, Fragment f) {
        if (f instanceof FragmentLifecycleable) {
            obtainSubject(f).onNext(FragmentEvent.PAUSE);
        }
    }

    @Override
    public void onFragmentStopped(FragmentManager fm, Fragment f) {
        if (f instanceof FragmentLifecycleable) {
            obtainSubject(f).onNext(FragmentEvent.STOP);
        }
    }

    @Override
    public void onFragmentViewDestroyed(FragmentManager fm, Fragment f) {
        if (f instanceof FragmentLifecycleable) {
            obtainSubject(f).onNext(FragmentEvent.DESTROY_VIEW);
        }
    }

    @Override
    public void onFragmentDestroyed(FragmentManager fm, Fragment f) {
        if (f instanceof FragmentLifecycleable) {
            obtainSubject(f).onNext(FragmentEvent.DESTROY);
        }
    }

    @Override
    public void onFragmentDetached(FragmentManager fm, Fragment f) {
        if (f instanceof FragmentLifecycleable) {
            obtainSubject(f).onNext(FragmentEvent.DETACH);
        }
    }

    private Subject<FragmentEvent> obtainSubject(Fragment fragment) {
        return ((FragmentLifecycleable) fragment).provideLifecycleSubject();
    }
}

跟 activity 類型,這裏也是根據方法的參數 fragment 判斷+強轉成 FragmentLifecycleable,然後獲取到 生命週期的上游事件發射器 Subject,發送一個生命週期事件出去。

最終使用時候

UserPresenter.java 業務類中使用
——————————————————————————————
Observable
        .just("yao")
        .compose(RxLifecycleUtils.bindToLifecycle(mRootView))//這個mRootView實際是一個activity/fragment
        .subscribe(new Consumer<String>() {
            @Override
            public void accept(String s) throws Exception {
            }
        });


RxLifecycleUtils.java
——————————————————————————————
    public static <T> LifecycleTransformer<T> bindToLifecycle(@NonNull IView view) {
        Preconditions.checkNotNull(view, "view == null");
        if (view instanceof Lifecycleable) {
            return bindToLifecycle((Lifecycleable) view);
        } else {
            throw new IllegalArgumentException("view isn't Lifecycleable");
        }
    }

    public static <T> LifecycleTransformer<T> bindToLifecycle(@NonNull Lifecycleable lifecycleable) {
        Preconditions.checkNotNull(lifecycleable, "lifecycleable == null");
        if (lifecycleable instanceof ActivityLifecycleable) {
            return RxLifecycleAndroid.bindActivity(((ActivityLifecycleable) lifecycleable).provideLifecycleSubject());
        } else if (lifecycleable instanceof FragmentLifecycleable) {
            return RxLifecycleAndroid.bindFragment(((FragmentLifecycleable) lifecycleable).provideLifecycleSubject());
        } else {
            throw new IllegalArgumentException("Lifecycleable not match");
        }
    }

因爲 MVPArms 涉及了很高 dagger2 和 Rxjava2 的用法,要深究的話就講不完了。所以簡略講一下,這裏大概的意思是,使用了 Rxjava2 的 compose 方法,傳進入一個 activity/fragment 的實例,裏面會把當前這個 Rxjava 序列和生命週期序列組成一個新的序列。這個新的序列收到某個生命週期事件,就會自我銷燬。

 

 

以上是兩者開源庫的方案,終極方案還是得靠 Google 的 Lifecycle。

ps:上一篇博客寫 LiveData,寫到一半發現要講清楚 LiveData 需要先講清楚 Lifecycle。沒辦法就在頭部插入了 Lifecycle 介紹的代碼。所以就把上篇博客講的 Lifecycle 部分再次在這粘貼一遍了。

!!! 官方 Lifecycle 方案 !!!

Lifecycle 可以理解爲一個庫或一堆類,加上在Activity、Fragment裏面插入的一些邏輯代碼,最終實現的生命週期可以通知到外界的體系。

 

像觀察者模式一樣。可以分爲註冊、反註冊、發送事件和接受事件這4部分。

先來看發送部分。

發送部分(處於源碼裏面)

上面這個圖以 android.support.v4.app.Fragment.java 爲例,可以看到從8.1.0開始,在 performCreate、performStart、performResume、performPause、performStop 和 performDestroy 等方法都加上了發送生命週期 Event 事件。

 

Activity 發送生命週期 Event 會複雜一點,是在 android.support.v4.app.SupportActivity 裏通過創建一個 ReportFragment,把在各個生命週期中發事件的代碼邏輯挪進去 ReportFragment 裏實現的。

這一招數讓我想起了 Glide 對於圖片生命週期的管理。Glide.with(Activity) 也是讓 Activity 創建出一個 Fragment ,在 Fragment 的各個生命週期方法內插入回調函數後,執行代碼來實現的。

SupportActivity.java(support庫)
------------------------------
    @Override
    @SuppressWarnings("RestrictedApi")
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ReportFragment.injectIfNeededIn(this);
    }


ComponentActivity.java(androidx庫)
------------------------------
    @Override
    @SuppressWarnings("RestrictedApi")
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ReportFragment.injectIfNeededIn(this);
    }


ReportFragment.java
------------------------------
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        dispatchCreate(mProcessListener);
        dispatch(Lifecycle.Event.ON_CREATE);
    }

    @Override
    public void onStart() {
        super.onStart();
        dispatchStart(mProcessListener);
        dispatch(Lifecycle.Event.ON_START);
    }

    @Override
    public void onResume() {
        super.onResume();
        dispatchResume(mProcessListener);
        dispatch(Lifecycle.Event.ON_RESUME);
    }

    @Override
    public void onPause() {
        super.onPause();
        dispatch(Lifecycle.Event.ON_PAUSE);
    }

    @Override
    public void onStop() {
        super.onStop();
        dispatch(Lifecycle.Event.ON_STOP);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        dispatch(Lifecycle.Event.ON_DESTROY);
        // just want to be sure that we won't leak reference to an activity
        mProcessListener = null;
    }

    private void dispatch(Lifecycle.Event event) {
        Activity activity = getActivity();
        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);
            }
        }
    }

Activity 和 Fragment 都會調用到 LifecycleRegistry.handleLifecycleEvent(event) 方法。

LifecycleRegistry 是在 ComponentActivity 和 Fragment 中聲明並且直接new出來的成員變量。

同時它們還是實現了 LifecycleOwner 接口,裏面的 getLifecycle() 就是返回這個 mLifecycleRegistry 用的。

SupportActivity.java(用於support庫)
------------------------------
public class SupportActivity extends Activity implements LifecycleOwner {

    private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);


ComponentActivity.java(用於androidx庫)
------------------------------
public class ComponentActivity extends Activity
        implements LifecycleOwner, KeyEventDispatcher.Component {

    private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);


Fragment.java
------------------------------
public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener, LifecycleOwner {

    LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);





LifecycleOwner.java
------------------------------
public interface LifecycleOwner {
    @NonNull
    Lifecycle getLifecycle();
}

用了 LifecycleRegistry 來管理註冊到Activity或Fragment來的所有觀察者。包括添加、刪除觀察者,接受生命週期事件並分發到各個觀察者中。

LifecycleRegistry 會維護一個 State 變量。同時這些觀察者 ObserverWithState 也會有維護一份屬於自己的聲明週期狀態 State。

這兩份 State 的作用是,兩者比較後,可以決定觀察者列表「從前往後遍歷」還是「從後往前遍歷」。爲什麼要分「從前往後遍歷」還是「從後往前遍歷」我猜可能是一些觀察者要遵循棧的後進先出原則吧,後註冊的一些觀察者組件需要先進行反註冊操作。

 

下面這圖是Lifecycles體系裏面 State 和 Event 的關係。

 

 

LifecycleRegistry.handleLifecycleEvent(event) 之後接着是

 LifecycleRegistry.sync() 方法,接着是

backwardPass() 或者 forwardPass(),代表從後往前遍歷還是從前往後遍歷。

在裏面會遍歷 LifecycleRegistry 的成員變量 mObserverMap,這個 Map 就是該 Activity/Fragment 生命週期的觀察者。遍歷 Map 後逐個調用 ObserverWithState.dispatchEvent(),最後執行 GenericLifecycleObserver.onStateChanged()。即逐個通知到觀察者,當前 Activity/Fragment 處於哪個生命週期裏了。

 

註冊、反註冊和接受通知(處於源碼外面,需要開發者寫)

說完發送生命週期通知事件後,就該講在外面我們如何使用觀察者監聽通知了,包括註冊、反註冊和接受通知。

簡單寫法一般有這麼兩種,這是第一種,註解聲明只接受 ON_RESUME 事件通知

這是第二種

註冊後可以成功收到相應事件。看logcat日誌,我把一個MainActivity打開又關閉後,輸出了這些日誌。

ps:GenericLifecycleObserver 下面報紅了,因爲這個類上面的註解說明了,這個類只應該在自己的library 裏面使用。可以忽略這個警告。看 GenericLifecycleObserver 頭像的註解,如下圖

 

 

總結:

早於 google 推出 Lifecycle 方案時,開源庫已經有了用 Activity/Fragment 生命週期監控的功能。谷歌在26.1.0算是推出了官方實現。Lifecycle 這一套還是很有用的,可以減少我們在各個生命週期回調中插入代碼,更加的解耦。民間已經開始使用 Lifecycle 寫一些比如 Handler 這種有銷燬需求的功能了,減少我們在 onDestroy 釋放資源的代碼。可能等到 26.1.0+ 佔據主流後,Glide 庫會改用這套方案,各個開源庫也會更多的使用到 Lifecycle 功能。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章