android生命周期神器--Lifecycle
文章目录
- 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); } } }
更多相关文章
- Android 访问Webservice接口,参数对象不能串行化问题解决(java.lan
- Glide的with()方法和生命周期的源码分析
- Android接口初了解
- Android学习笔记4——Activity的生命周期
- android: 生命周期
- 零碎知识点回顾——Activity横竖屏切换的生命周期
- Android 9.0 (P版本) 亮度控制接口变更