文章目录

  • android生命周期神器--Lifecycle
    • Lifecycle源码分析
      • LifecycleOwner
      • Lifecycle
      • LifecycleObserver
      • LifecycleRegistry
    • 问题
      • 生命周期通知大部分是在Fragment中触发的,那没有Fragment的Activity呢?它的生命周期通知是啥时触发的
      • 为啥要用ViewModelProviders去创建ViewModel的实例
      • 为啥说ViewModel放入Viewmodelstore后在Activity Destroy后会自动释放资源
      • 为啥说在ViewModel不能持有Activity或Fragment的引用
      • 为啥说LiveData在Activity或Fragment不可见时不会去通知观察者

android生命周期神器–Lifecycle

  • 官方文档: https://developer.android.google.cn/topic/libraries/architecture/lifecycle#java
  • 从官方借用下图片

Lifecycle源码分析

  • 首先梳理下Activity和Lifecycle接口等的继承关系
//activity继承关系AppCompatActivity-->FragmentActivity--> androidx.activity.ComponentActivity(ViewModelStoreOwner,LifecycleOwner)-->androidx.core.app.ComponentActivity(LifecycleOwner)-->Activity//fragment继承关系androidx.fragment.app.Fragment(LifecycleOwner)androidx.lifecycle.ReportFragment-->android.app.Fragment(过时)//Lifecycle继承关系LifecycleRegistryOwner(interface,已过时)-->LifecycleOwner(interface)//Lifecycle只是抽象类,LifecycleRegistry是Lifecycle的唯一子类,实现了其抽象方法LifecycleRegistry-->Lifecycle(abstract)
  • 上面中用–>表示继承关系,括号则表示实现的接口,于是我们可以看到我们经常使用的AppCompatActivity是继承于FragmentActivity,FragmentActivity又继承于ComponentActivity,ComponentActivity实现了LifecycleOwner接口,然而androidx.activity.ComponentActivity又继承了
    androidx.core.app.ComponentActivity,这个ComponentActivity也实现了LifecycleOwner接口,从这里可以看出要分析生命周期神器LIfecycle就要从LifecycleOwner这个接口入手了

LifecycleOwner

  • 那么LifecycleOwner接口到底长啥样呢
public interface LifecycleOwner {    /**     * Returns the Lifecycle of the provider.     *     * @return The lifecycle of the provider.     */    @NonNull    Lifecycle getLifecycle();}
  • LifecycleOwner 接口很简单,就是要返回一个Lifecycle,那么Lifecycle又是什么呢

Lifecycle

public abstract class Lifecycle {    /**     * Lifecycle coroutines extensions stashes the CoroutineScope into this field.     *     * @hide used by lifecycle-common-ktx     */    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)    @NonNull    AtomicReference<Object> mInternalScopeRef = new AtomicReference<>();    /**     * Adds a LifecycleObserver that will be notified when the LifecycleOwner changes     * state.     * 

* The given observer will be brought to the current state of the LifecycleOwner. * For example, if the LifecycleOwner is in {@link State#STARTED} state, the given observer * will receive {@link Event#ON_CREATE}, {@link Event#ON_START} events. * * @param observer The observer to notify. */ @MainThread public abstract void addObserver(@NonNull LifecycleObserver observer); /** * Removes the given observer from the observers list. *

* If this method is called while a state change is being dispatched, *

    *
  • If the given observer has not yet received that event, it will not receive it. *
  • If the given observer has more than 1 method that observes the currently dispatched * event and at least one of them received the event, all of them will receive the event and * the removal will happen afterwards. *
* * @param observer The observer to be removed. */
@MainThread public abstract void removeObserver(@NonNull LifecycleObserver observer); /** * Returns the current state of the Lifecycle. * * @return The current state of the Lifecycle. */ @MainThread @NonNull public abstract State getCurrentState(); @SuppressWarnings("WeakerAccess") public enum Event { ON_CREATE, ON_START, ON_RESUME, ON_PAUSE, ON_STOP, ON_DESTROY, ON_ANY } /** * Lifecycle states. You can consider the states as the nodes in a graph and * {@link Event}s as the edges between these nodes. */ @SuppressWarnings("WeakerAccess") public enum State { /** * Destroyed state for a LifecycleOwner. After this event, this Lifecycle will not dispatch * any more events. For instance, for an {@link android.app.Activity}, this state is reached * right before Activity's {@link android.app.Activity#onDestroy() onDestroy} call. */ DESTROYED, /** * Initialized state for a LifecycleOwner. For an {@link android.app.Activity}, this is * the state when it is constructed but has not received * {@link android.app.Activity#onCreate(android.os.Bundle) onCreate} yet. */ INITIALIZED, /** * Created state for a LifecycleOwner. For an {@link android.app.Activity}, this state * is reached in two cases: *
    *
  • after {@link android.app.Activity#onCreate(android.os.Bundle) onCreate} call; *
  • right before {@link android.app.Activity#onStop() onStop} call. *
*/
CREATED, /** * Started state for a LifecycleOwner. For an {@link android.app.Activity}, this state * is reached in two cases: *
    *
  • after {@link android.app.Activity#onStart() onStart} call; *
  • right before {@link android.app.Activity#onPause() onPause} call. *
*/
STARTED, /** * Resumed state for a LifecycleOwner. For an {@link android.app.Activity}, this state * is reached after {@link android.app.Activity#onResume() onResume} is called. */ RESUMED; /** * Compares if this State is greater or equal to the given {@code state}. * * @param state State to compare with * @return true if this State is greater or equal to the given {@code state} */ public boolean isAtLeast(@NonNull State state) { return compareTo(state) >= 0; } }}
  • 从代码里我们可以看到Lifecycle是一个抽象类,里面还定义了生命周期的相关事件和状态的枚举,还有添加删除观察者等,观察者关键就是LifecycleObserver 这个接口,让我们看看它的真面目

LifecycleObserver

/** * Marks a class as a LifecycleObserver. It does not have any methods, instead, relies on * {@link OnLifecycleEvent} annotated methods. * 

* @see Lifecycle Lifecycle - for samples and usage patterns. */public interface LifecycleObserver {}

  • 我们发现这个接口里面啥也没有,仅仅只是一个标记接口,这个标记接口可以配合注解OnLifecycleEvent对生命周期进行观察,如
class MyObserver : LifecycleObserver {        @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)        fun connectListener() {            ...        }        @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)        fun disconnectListener() {            ...        }    }    myLifecycleOwner.getLifecycle().addObserver(MyObserver())
  • 同时LifecycleEventObserver和FullLifecycleObserver是两个继承于LifecycleObserver的接口
interface FullLifecycleObserver extends LifecycleObserver {    void onCreate(LifecycleOwner owner);    void onStart(LifecycleOwner owner);    void onResume(LifecycleOwner owner);    void onPause(LifecycleOwner owner);    void onStop(LifecycleOwner owner);    void onDestroy(LifecycleOwner owner);}public interface LifecycleEventObserver extends LifecycleObserver {    /**     * Called when a state transition event happens.     *     * @param source The source of the event     * @param event The event     */    void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event);}
  • 当我们调用LifecycleRegistry.addObserver时,内部其实使用的就是LifecycleEventObserver,它被包装在ObserverWithState中,当我们调用LifecycleRegistry.setCurrentState时,实际上就是调用LifecycleRegistry.moveToState,最终回调到LifecycleEventObserver里的onStateChanged方法

LifecycleRegistry

  • LifecycleRegistry是抽象类Lifecycle的唯一实现类
public class LifecycleRegistry extends Lifecycle {    private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap =            new FastSafeIterableMap<>();  ...      /**     * Moves the Lifecycle to the given state and dispatches necessary events to the observers.     *     * @param state new state     */    @MainThread    public void setCurrentState(@NonNull State state) {        moveToState(state);    }    /**     * Sets the current state and notifies the observers.     * 

* Note that if the {@code currentState} is the same state as the last call to this method, * calling this method has no effect. * * @param event The event that was received */ public void handleLifecycleEvent(@NonNull Lifecycle.Event event) { State next = getStateAfter(event); moveToState(next); }... }

  • 看到这里我们大概就有点眉目了,LifecycleRegistry就是最核心的所在,它继承了Lifecycle这个抽象类,拥有了添加观察者的能力,同时又对外提供了handleLifecycleEvent和setCurrentState两个方法,赋予外界设置状态的能力,也就是当状态发生变化时可以通知给LifecycleRegistry,然后LifecycleRegistry再将事件通知给观察者,观察者收到事件后就可以做相应的处理,比如在页面不可见时直接忽略页面的更新等
  • 那么LifecycleRegistry这个重要的对象是在哪被实例化的呢,我们可以在ComponentActivity中找到答案
  • 在androidx.activity.ComponentActivity中,以下只保留了关键代码
public class ComponentActivity extends androidx.core.app.ComponentActivity implements        LifecycleOwner,        ViewModelStoreOwner {   private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);   private ViewModelStore mViewModelStore;          @NonNull    @Override    public Lifecycle getLifecycle() {        return mLifecycleRegistry;    }    @NonNull    @Override    public ViewModelStore getViewModelStore() {    ...     if (mViewModelStore == null) {         mViewModelStore = new ViewModelStore();     }        return mViewModelStore;    } }

虽然androidx.core.app.ComponentActivity中也实现了LifecycleOwner接口,但已经被子类androidx.activity.ComponentActivity覆盖了,因此我们只需要关心androidx.activity.ComponentActivity的LifecycleOwner即可

  • 从上面代码中可以看出,LifecycleRegistry 实例就是在ComponentActivity中被new出来的,然后通过getLifecycle方法进行返回,这里就把LifecycleOwner这个接口串连起来了
  • 从上面的分析中我们就可以知道,我们可以通过LifecycleOwner接口拿到LifecycleRegistry 实例对象,然后进行添加观察者,这样就可以监听到生命周期事件了,LiveData就是这样干的,我们可以看看LivaData的observe方法
public abstract class LiveData<T> { ... @MainThread    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {        assertMainThread("observe");        if (owner.getLifecycle().getCurrentState() == DESTROYED) {            // ignore            return;        }        LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);        ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);        if (existing != null && !existing.isAttachedTo(owner)) {            throw new IllegalArgumentException("Cannot add the same observer"                    + " with different lifecycles");        }        if (existing != null) {            return;        }        owner.getLifecycle().addObserver(wrapper);    } }
  • 实际上FragmentActivity中也实例了LifecycleRegistry对象,并且在内部类HostCallbacks 中覆盖了getLifecycle方法,主要代码如下
public class FragmentActivity extends ComponentActivity  {    ...final FragmentController mFragments = FragmentController.createController(new HostCallbacks());    /**     * A {@link Lifecycle} that is exactly nested outside of when the FragmentController     * has its state changed, providing the proper nesting of Lifecycle callbacks     * 

* TODO(b/127528777) Drive Fragment Lifecycle with LifecycleObserver */ final LifecycleRegistry mFragmentLifecycleRegistry = new LifecycleRegistry(this);... class HostCallbacks extends FragmentHostCallback<FragmentActivity> implements ViewModelStoreOwner, OnBackPressedDispatcherOwner { public HostCallbacks() { super(FragmentActivity.this /*fragmentActivity*/); } @NonNull @Override public Lifecycle getLifecycle() { // Instead of directly using the Activity's Lifecycle, we // use a LifecycleRegistry that is nested exactly outside of // when Fragments get their lifecycle changed // TODO(b/127528777) Drive Fragment Lifecycle with LifecycleObserver return mFragmentLifecycleRegistry; } } }

  • 对于以上FragmentActivity的Lifecycle 用法暂时未知作用,这里做下记录,留待以后深究

  • 另外还有其他问题就是生命周期究竟是在哪触发的呢,这个问题从下图我们就可以看到就是在Fragment和FragmentActivity中触发的

问题

  • 下面以提问的方式对Lifecycle进行介绍

生命周期通知大部分是在Fragment中触发的,那没有Fragment的Activity呢?它的生命周期通知是啥时触发的

  • 一开始我也很奇怪,生命周期事件大多都是在Fragment中发出的,那Activity呢?后面才知道为了降低侵入性,增加了一个ReportFragment,ComponentActivity在onCreate时就执行了ReportFragment.injectIfNeededIn(this);,从而将生命周期转移到Fragment,由Fragment进行触发了

  • ReportFragment的生命周期会通知到其对应Activity的LifecycleRegistry,再由LifecycleRegistry通知到观察者

    public class ComponentActivity extends Activity        implements LifecycleOwner, KeyEventDispatcher.Component {...    @Override    @SuppressWarnings("RestrictedApi")    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);         /////////////////////重点//////////////////////////     //关键就是这一步判断,它会添加ReportFragment     /////////////////////重点//////////////////////////        ReportFragment.injectIfNeededIn(this);    }    ...    }
    public class ReportFragment extends Fragment {    private static final String REPORT_FRAGMENT_TAG = "androidx.lifecycle"            + ".LifecycleDispatcher.report_fragment_tag";    public static void injectIfNeededIn(Activity activity) {        // ProcessLifecycleOwner should always correctly work and some activities may not extend        // FragmentActivity from support lib, so we use framework fragments for activities        android.app.FragmentManager manager = activity.getFragmentManager();        if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {            manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();            // Hopefully, we are the first to make a transaction.            manager.executePendingTransactions();        }    }   }

为啥要用ViewModelProviders去创建ViewModel的实例

  • 首先说下原因,这是为了在适当的时机去销毁ViewModel所占用的资源,同时也为了实现多实例共享同一个ViewModel

  • 接着就说明是如何做到以上两点的,请看下面分析

  • 为了更直观些,现把Activity的继承关系梳理下,其中括号表示接口

    AppCompatActivity–>FragmentActivity–>ComponentActivity(LifecycleOwner,ViewModelStoreOwner)–>Activity

  • 为了让Activity自动管理ViewModel,我们就需要利用ViewModelProviders.of(this).get(XXViewModel.class);得到ViewModel对象

  • 至于为啥要用这个去创建ViewModel,是因为其在内部通过this对象拿到了ViewModelStore对象,这个ViewModelStore就是保存了当前对象所持有的ViewModel(说白了ViewModelStore就是一个HaspMap的简单封装而已,用于存储ViewModel),拿到ViewModelStore对象就可以通过XXViewModel.class这个key去得到ViewModel对象,这时ViewModelStore不一定存在此key对应的ViewModel对象,如果没有那么就通过KeyedFactory去创建一个了,再把刚创建的塞回ViewModelStore。

  • 这样跟我们单独new一个ViewModel对象有啥区别呢?我们单独new的对象并没有加入到ViewModelStore里管理,因此ViewModel是独立的,一个实例对象里的viewModel无法被其他实例访问到,假如我们的场景就是这样的,ViewModel并不需要在多个实例中共享一个,那么简单new一个也没啥问题;假如我们需要在多个实例中共享同一个ViewModel,那么通过ViewModelProviders来获取ViewModel就是比较好的办法了;

  • 那么什么场景下有共享ViewModel的需求呢,比如你想在Activity下的多个Fragment之间共用一个ViewModel,那么利用ViewModelProviders就是最方便快捷的选择。

  • 通过ViewModelProviders会将ViewModel存储进ViewmodelStore,ViewmodelStore由于ViewModelStoreOwner接口的原因可以被生命周期获取到进而进行管理,也就是会在适当的时机帮你销毁viewmodel的资源,同时有了ViewmodelStore的管理也能轻而易举实现多个Fragment共享同一个Viewmodel,显然自己手动new一个Viewmodel是没有这些好处的

  • 因此总结下来就是,Viewmodel最好不要手动创建,交给ViewModelProviders去管理,那么事情会变得简单而且不易出错。

  • 当然,如果你的Viewmodel非常简单,既没有共享的需求,也没什么资源需要特别释放(即不需要在ViewModel.onCleared里操作什么),那么手动创建也是可以的。

  • 如果你想说自己手动创建viewmodel后扔进viewmodelstore里,不好意思,办不到,因为目前Viewmodelstore的put方法并不是public的(反射不推荐),因此乖乖用ViewModelProviders吧

为啥说ViewModel放入Viewmodelstore后在Activity Destroy后会自动释放资源

  • 原因就在ComponentActivity里查找
  • 从代码中我们很清楚看到ComponentActivity添加了一个观察者,当销毁时就会调用clear方法

为啥说在ViewModel不能持有Activity或Fragment的引用

  • 因为viewmodel的生命周期比activity长,如果activity configuration发生变化(比如屏幕旋转),新的实例会重新使用已存在的viewmodel,试想一下,如果viewmodel持有旧activity的引用,那么就会导致旧activity无法被回收,造成内存泄漏
  • 那么为何说ViewModel的生命周期比activity长呢,因为ViewModel是可以给多个实例共用的,这就导致ViewModel的生命周期大于引用它的多实例中生命周期最短的那一个,简单点来说,就是ViewModel被一个存活10秒和20秒的实例引用,那么ViewModel就存活20秒(20>10)

为啥说LiveData在Activity或Fragment不可见时不会去通知观察者

  • 我们知道在使用LiveData添加观察者时需要添加LifecycleOwner和Observer,添加的这两个对象实际上会被包装在LifecycleBoundObserver中,LifecycleBoundObserver.shouldBeActive就是根据当前状态判断是否需要通知观察者,而LiveData决定是否通知观察者就是在LiveData.considerNotify(ObserverWrapper observer)方法中处理的,可想而知,此方法中就是用到了LifecycleBoundObserver.shouldBeActive()作出决定的
  • 这里说明一下,LifecycleBoundObserver是LiveData的内部类,LifecycleBoundObserver继承了抽象类ObserverWrapper
  • LiveData部分代码如下,主要看重点标记的代码
    public abstract class LiveData<T> {private void considerNotify(ObserverWrapper observer) {        if (!observer.mActive) {            return;        }        /////////////////////重点//////////////////////////        //关键就是这一步判断,如果不可见直接就返回了,不会去通知观察者        /////////////////////重点//////////////////////////        if (!observer.shouldBeActive()) {            observer.activeStateChanged(false);            return;        }        if (observer.mLastVersion >= mVersion) {            return;        }        observer.mLastVersion = mVersion;        //noinspection unchecked        observer.mObserver.onChanged((T) mData);    }class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {        @NonNull        final LifecycleOwner mOwner;        LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {            super(observer);            mOwner = owner;        }        /////////////////////重点////////////////////////////关键就是这一步判断,最新状态如果是STARTED才会去通知观察者/////////////////////重点//////////////////////////        @Override        boolean shouldBeActive() {            return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);        }     } }

更多相关文章

  1. BiliBili-IJKPlayer播放器源码分析(一)
  2. Android(安卓)LCD(二):LCD常用接口原理篇
  3. Android(安卓)访问Webservice接口,参数对象不能串行化问题解决(jav
  4. android Camera模块分析
  5. RxAndroid入门-传智播客
  6. Glide的with()方法和生命周期的源码分析
  7. Android生命周期
  8. Android接口初了解
  9. android Camera模块分析

随机推荐

  1. Android(安卓)TextView文字横向自动滚动(
  2. Android 技术专题系列之三 -- 编译(build)
  3. Android 相对布局:RelativeLayout
  4. Android分区解释:boot, system, recovery,
  5. Android(安卓)init 启动过程分析1
  6. Android平板上开发应用的一点心得——精
  7. 使用Lint 和 Annotations来提升代码质量
  8. Android(安卓)Handler 异步消息处理机制
  9. android 莫名出现Conversion to Dalvik f
  10. anctionbar样式 自定义属性