Lifecycle使用介绍
Lifecycle是google提供的一个可以监听activity、fragment、service、app process生命周期的组件库
我们最常用的是监听activity和fragment生命周期,比如使用MVP架构,Presenter一般需要在activity的oncreate方法中初始化变量和资源等,在ondestory中释放资源等
如果我们不用Lifecycle组件的写法是这样的,必须手动在activity的onCreate和onDestroy方法调presenter对应的方法
class LifecycleActivity : AppCompatActivity() {
private lateinit var presenter: LifecyclePresenter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_lifecycle)
presenter = LifecyclePresenter(this)
presenter.onCreate()
}
override fun onDestroy() {
super.onDestroy()
presenter.onDestroy()
}
...
}
很显然 这样非常不优雅
那我们该如何使用Lifecycle组件库呢?
下面主要以Presenter为Example讲解
针对Activity
先定义一个ActivityPresenter
// 先定义一个BasePresenter,并定义对应activity的一系列方法
open class BasePresenter : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
open fun onCreate(owner: LifecycleOwner) {
}
@OnLifecycleEvent(Lifecycle.Event.ON_START)
open fun onStart(owner: LifecycleOwner) {
}
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
open fun onResume(owner: LifecycleOwner) {
}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
open fun onPause(owner: LifecycleOwner) {
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
open fun onStop(owner: LifecycleOwner) {
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
open fun onDestroy(owner: LifecycleOwner) {
}
}
// 定义一个 IActivityView
interface IActivityView {
fun showContent(content: String)
}
// 继承BasePresenter,只需要重写 需要的生命周期方法即可
class ActivityPresenter(var view: IActivityView) : BasePresenter() {
private var disposable: Disposable? = null
private var i = 0
override fun onCreate(owner: LifecycleOwner) {
super.onCreate(owner)
loadData()
}
override fun onDestroy(owner: LifecycleOwner) {
super.onDestroy(owner)
disposable?.dispose()
}
private fun loadData() {
disposable = Flowable.interval(1, 1, TimeUnit.SECONDS)
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(object : DisposableSubscriber<Any>() {
override fun onComplete() {}
override fun onNext(t: Any?) {
view.showContent("lifecycle: " + i++.toString())
}
override fun onError(t: Throwable?) {}
})
}
}
然后 主要的 activity代码实现如下:
// 注意实现LifecycleOwner接口
class LifecycleActivity : Activity(), LifecycleOwner, IActivityView {
private lateinit var lifecycleRegistry: LifecycleRegistry
private lateinit var presenter: ActivityPresenter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_lifecycle)
// 先创建一个LifecycleRegistry对象
lifecycleRegistry = LifecycleRegistry(this)
// 然后在activity对应的每个生命周期方法中调用handleLifecycleEvent
lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE)
presenter = ActivityPresenter(this)
// 调用addObserver方法,presenter开始观察activity生命周期
lifecycle.addObserver(presenter)
}
override fun onStart() {
super.onStart()
lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START)
}
override fun onResume() {
super.onResume()
lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME)
}
override fun onPause() {
super.onPause()
lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE)
}
override fun onStop() {
super.onStop()
lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP)
}
override fun onDestroy() {
super.onDestroy()
lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY)
}
//实现getLifecycle方法,返回上面定义好的lifecycleRegistry对象
override fun getLifecycle(): Lifecycle {
return lifecycleRegistry
}
override fun showContent(content: String) {
tv_text.text = content
}
}
可见步骤如下:
-
- 先定义一个class 实现
LifecycleObserver接口(比如:BasePresenter)
- 先定义一个class 实现
-
- 再定义一系列的方法 并加上
@OnLifecycleEvent注解,映射对应Activity的生命周期方法
- 再定义一系列的方法 并加上
-
- 然后定义一个
Activity(比如上面的LifecycleActivity)实现LifecycleOwner接口,并实例化一个LifecycleRegistry对象,在getLifecycle()方法中返回此对象
- 然后定义一个
-
- 然后在
activity的每个生命周期方法中调用handleLifecycleEvent方法,设置并通知Observer当前activity当前生命周期
- 然后在
-
- 最后调用
lifecycle的addObserver方法,使得ActivityPresenter具有监听activity生命周期的能力
- 最后调用
上面的实现可能比较繁琐,那是因为我们使用的是Activity,而不是FragmentActivity; 对于Activity 在sdk源码中没有帮我们实现LifecycleOwner接口, 需要我们自己手动实现
那为什么需要我们手动在activity的生命周期方法中手动调用handleLifecycleEvent方法呢,能不能不写呢?答案当然是可以不写的,但是你必须导入lifecycle-extensions库
implementation "androidx.lifecycle:lifecycle-extensions:2.0.0"
如果你导入了lifecycle-extensions库,那么就不需要你手动调handleLifecycleEvent方法了, 只需要实现LifecycleOwner接口即可
class LifecycleActivity : Activity(), LifecycleOwner, IActivityView {
private lateinit var lifecycleRegistry: LifecycleRegistry
private lateinit var presenter: ActivityPresenter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_lifecycle)
// 先创建一个LifecycleRegistry对象
lifecycleRegistry = LifecycleRegistry(this)
presenter = ActivityPresenter(this)
// 调用addObserver方法,presenter开始观察activity生命周期
lifecycle.addObserver(presenter)
}
//实现getLifecycle方法,返回上面定义好的lifecycleRegistry对象
override fun getLifecycle(): Lifecycle {
return lifecycleRegistry
}
override fun showContent(content: String) {
tv_text.text = content
}
}
针对FragmentActivity
对于support 包(或androidx包)下的FragmentActivity ,在Support Library 26.1.0起 就已经在源码层 实现了LifecycleOwner接口,不需要开发者手动实现LifecycleOwner接口,同时也不需要手动调用handleLifecycleEvent方法
// AppCompatActivity 继承 FragmentActivity
class LifecycleFragmentActivity : AppCompatActivity(), IView {
private lateinit var presenter: LifecyclePresenter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_lifecycle)
presenter = LifecyclePresenter(this)
lifecycle.addObserver(presenter)
}
override fun showContent(content: String) {
tv_text.text = content
}
}
现在是不是感觉非常简单,只需要定义一个class 实现 LifecycleObserver 接口,然后通过FragmentActivity自带的lifecycle对象调用addObserver方法即可
针对support包(或androidx包)下的Fragment
对于support包(或androidx包)下的fragment,在Support Library 26.1.0起 就已经在源码层 实现了LifecycleOwner接口,不需要开发者手动实现LifecycleOwner接口,同时也不需要手动调用handleLifecycleEvent方法
class AndroidXFragment : Fragment(), IFragmentView {
private lateinit var presenter: FragmentPresenter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
presenter = FragmentPresenter(this)
// 调用addObserver方法就可以监听Fragment生命周期了
lifecycle.addObserver(presenter)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_lifecycle, container, false)
}
override fun showContent(content: String) {
tv_text?.text = content
}
}
interface IFragmentView {
fun showContent(content: String)
}
class FragmentPresenter(val view: IFragmentView) : BasePresenter() {
private var disposable: Disposable? = null
private var i = 0
override fun onCreate(owner: LifecycleOwner) {
super.onCreate(owner)
loadData()
}
override fun onDestroy(owner: LifecycleOwner) {
super.onDestroy(owner)
disposable?.dispose()
}
private fun loadData() {
disposable = Flowable.interval(1, 1, TimeUnit.SECONDS)
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(object : DisposableSubscriber<Any>() {
override fun onComplete() {}
override fun onNext(t: Any?) {
view.showContent("Fragment lifecycle: " + i++.toString())
}
override fun onError(t: Throwable?) {}
})
}
}
针对app包下的Fragment
对于app包下的Fragment, 跟app包下的Activity道理一样,在sdk 源码层 没有帮我们实现LifecycleOwner接口,所以需要我们手动实现LifecycleOwner接口
同时与Activity不一样的是,即使 你导入了lifecycle-extensions库,你也必须手动调用handleLifecycleEvent方法
class AppFragment : Fragment(), LifecycleOwner, IFragmentView {
private lateinit var lifecycleRegistry: LifecycleRegistry
private lateinit var presenter: FragmentPresenter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
lifecycleRegistry = LifecycleRegistry(this)
lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE)
presenter = FragmentPresenter(this)
lifecycle.addObserver(presenter)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_lifecycle, container, false)
}
override fun onStart() {
super.onStart()
lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START)
}
override fun onResume() {
super.onResume()
lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME)
}
override fun onPause() {
super.onPause()
lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE)
}
override fun onStop() {
super.onStop()
lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP)
}
override fun onDestroy() {
super.onDestroy()
lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY)
}
override fun showContent(content: String) {
tv_text?.text = content
}
override fun getLifecycle(): Lifecycle {
return lifecycleRegistry
}
}
可见监听在app包下的Fragment生命周期,还是比较蛋疼的,需要写的代码比较多
但是在实际应用过程中我们大部分情况下都是使用的support包(或androidx包)下的fragment;同时google也已经标示app包下的fragment已过期,推荐我们使用support包(或androidx包)下的fragment
/*
* ...
* ...
* @deprecated Use the <a href="{@docRoot}tools/extras/support-library.html">Support Library</a>
* {@link android.support.v4.app.Fragment} for consistent behavior across all devices
* and access to <a href="{@docRoot}topic/libraries/architecture/lifecycle.html">Lifecycle</a>.
*/
@Deprecated
public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListener {
...
}
如何监听service生命周期呢
基本上监听service生命周期的需求很少,但是我们还是可以了解一下
同理 如果我们手动实现的话,一样需要先实现LifecycleOwner,在实例化一个LifecycleRegistry对象,然后在生命周期方法中不断调用handleLifecycleEvent方法,最后通过addObserver方法监听
但是庆幸的是google提供了一个LifecycleService,我们只需要让我们的Service继承LifecycleService即可
class TestLifecycleService : LifecycleService() {
private lateinit var testServicePresenter: TestServicePresenter
override fun onCreate() {
super.onCreate()
testServicePresenter = TestServicePresenter()
lifecycle.addObserver(testServicePresenter)
}
}
这样的话TestServicePresenter 就可以监听到service的生命周期
监听Service 生命周期回调规则如下
| service生命周期 | LifecycleObserver生命周期回调 |
|---|---|
| onCreate | onCreate |
| onBind | onStart |
| onStart | onStart |
| onDestroy | 先onStop,然后onDestroy |
如何监听整个app的生命周期呢
有些时候我们需要监听整个app生命周期,当app退到后台和进入前台需要做一些业务逻辑处理等
一般情况下监听app前后台切换的方法如下:
监听所有activity生命周期方法,同时定义一个counter计数和isForeground(默认false)前台标示,当每一个activity onResume时counter加1,同时如果发现isForeground是false,这表示app进入前台,同时将isForeground设置成true,当onPause时counter减1,并且当counter == 0时,用handler postDelayed(大概500毫秒左右)检查counter是否等于0,如果等于0,这表示app进入后台,同时将isForeground设置成false
大改的逻辑是这样的,可能还有一些特殊情况需要慢慢测试和代码调整
这里有一个别人写的监听app前后台切换的库Foredroid供大家参考
那如果我们用Lifecycle 该怎么实现呢??
很简单,一句代码就搞定了
ProcessLifecycleOwner.get().lifecycle.addObserver(TestProcessLifecyclePresenter())
Lifecycle监听app生命周期回调规则如下
| 触发回调规则 | LifecycleObserver生命周期回调 |
|---|---|
| 当app第一次启动的时候标示 | onCreate |
| 当mStartedCounter == 1 | onStart |
| 当mResumedCounter == 1 | onResume |
| 当mResumedCounter == 0 | onPause |
| 当mStartedCounter == 0 | onStop |
mStartedCounter 标示 当前有几个activity处于onStart状态
mResumedCounter 标示 当前有几个activity处于onResume状态
注意:当所有activity 被destroy时,是不会调LifecycleObserver的onDestroy方法的,这意味着无法监听到整个app的Destroy状态(onDestroy回调永远都不会调用)
Lifecycle 原理分析
Lifecycle组件库是怎么监听activity、fragment生命周期的呢?
Lifecycle组件库监听activity生命周期原理
如果我们不用Lifecycle组件库, 自己实现的话,一般想到的是定义一个BaseActivity,然后在BaseActivity的每个生命周期方法中调用一个方法 通知Observer(观察者) 当前activity处理哪个生命周期方法
上面的实现可能比较low,而且有局限性,它要求你的activity必须实现BaseActivity,有没有其它方式呢,答案是有的
先想想Fragment生命周期 跟 Activity有什么关系;是不是当activity 处于onResume, fragment 也处于onResume状态,当activity 处于onPause,fragment也处于onPause状态, 当activity 处于onDestroy,fragment也处于onDestroy状态;这样的话是不是就可以使用一个Fragment就可以监听当前Activity生命周期的变化,那我们就只需要给Activity添加一个空的Fragment即可
其时Lifecycle的是现实原理也是给Activity添加一个空的Fragment实现的(如果你看了Glide监听activity的实现原理的话,其时Glide也是这样实现的)
-
先查查 FragmentActivity 源码中是不是添加了一个空的
Fragment// 对于androidx包的FragmentActivity继承ComponentActivity // 对于support包的FragmentActivity继承SupportActivity,一样的有如下代码 @RestrictTo(LIBRARY_GROUP) public class ComponentActivity extends Activity implements LifecycleOwner, KeyEventDispatcher.Component { ... @Override @SuppressWarnings("RestrictedApi") protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); ReportFragment.injectIfNeededIn(this); } ... }可见确实在activity onCreate方法中添加了一个
ReportFragment;注意:ComponentActivity实现了LifecycleOwner接口,这也是为什么我们使用FragmentActivity 不需要手动实现LifecycleOwner接口的原因 -
接下来看看
ReportFragment源码是怎么写的@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) 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(); } } static ReportFragment get(Activity activity) { return (ReportFragment) activity.getFragmentManager().findFragmentByTag( REPORT_FRAGMENT_TAG); } private ActivityInitializationListener mProcessListener; private void dispatchCreate(ActivityInitializationListener listener) { if (listener != null) { listener.onCreate(); } } private void dispatchStart(ActivityInitializationListener listener) { if (listener != null) { listener.onStart(); } } private void dispatchResume(ActivityInitializationListener listener) { if (listener != null) { listener.onResume(); } } @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); } } } void setProcessListener(ActivityInitializationListener processListener) { mProcessListener = processListener; } interface ActivityInitializationListener { void onCreate(); void onStart(); void onResume(); } }可见 在
ReportFragment生命周期方法中都调用了dispatch方法,而在dispatch方法中都调用了handleLifecycleEvent方法;这样的话是不是就知道了为什么对于FragmentActivity就不需要手动调用handleLifecycleEvent方法了 -
为什么对于App包下的Activity, 需要我们手动调用
handleLifecycleEvent方法,当导入了lifecycle-extensions库之后,又不需要手动调用handleLifecycleEvent方法呢我们需要手动调用
handleLifecycleEvent方法,是因为在Activity源码里没有帮我们添加ReportFragment;那导入lifecycle-extensions依赖之后呢?先看看导入
lifecycle-extensions依赖之后,它都做了什么你会发现当导入
lifecycle-extensions依赖之后,多了一系列lifecycle扩展库;其中我们比较关心的是lifecycle-process;它里面有一个LifecycleDispatcher类,先看看它的源码class LifecycleDispatcher { private static AtomicBoolean sInitialized = new AtomicBoolean(false); static void init(Context context) { if (sInitialized.getAndSet(true)) { return; } ((Application) context.getApplicationContext()) .registerActivityLifecycleCallbacks(new DispatcherActivityCallback()); } @SuppressWarnings("WeakerAccess") @VisibleForTesting static class DispatcherActivityCallback extends EmptyActivityLifecycleCallbacks { @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) { ReportFragment.injectIfNeededIn(activity); } @Override public void onActivityStopped(Activity activity) { } @Override public void onActivitySaveInstanceState(Activity activity, Bundle outState) { } } private LifecycleDispatcher() { } }可见它使用了
Application的registerActivityLifecycleCallbacks注册了一个DispatcherActivityCallback对象,并在onActivityCreated回调中添加了ReportFragment,而在ReportFragment类中会自动调用handleLifecycleEvent方法LifecycleDispatcher的init方法是什么时候调用的呢??你会发现
lifecycle-process库里有一个ProcessLifecycleOwnerInitializer类@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) public class ProcessLifecycleOwnerInitializer extends ContentProvider { @Override public boolean onCreate() { LifecycleDispatcher.init(getContext()); ProcessLifecycleOwner.init(getContext()); return true; } @Nullable @Override public Cursor query(@NonNull Uri uri, String[] strings, String s, String[] strings1, String s1) { return null; } @Nullable @Override public String getType(@NonNull Uri uri) { return null; } @Nullable @Override public Uri insert(@NonNull Uri uri, ContentValues contentValues) { return null; } @Override public int delete(@NonNull Uri uri, String s, String[] strings) { return 0; } @Override public int update(@NonNull Uri uri, ContentValues contentValues, String s, String[] strings) { return 0; } }你会发现
ProcessLifecycleOwnerInitializer是一个ContentProvider(ProcessLifecycleOwnerInitializer会自动在你的AndroidManifest.xml中注册),LifecycleDispatcher是在ContentProvider的onCreate()初始化的,而ContentProvider的onCreate()调用时机是介于Application的attachBaseContext和onCreate之间,也就是app启动的时候调用除了知道
LifecycleDispatcher的init方法调用时机之外,你是不是发现了一块新大陆,原来我们可以定义一个ContentProvider巧妙的初始化我们的一些Library, 做到开发无感知,只需要添加依赖即可如果你细心的话,你会发现
ProcessLifecycleOwner也是在ContentProvider的onCreate()初始化的(ProcessLifecycleOwner是用来监听整个app生命周期的)
针对监听activity生命周期原理就先讲到这里,下面我们看看监听fragment生命周期原理
Lifecycle组件库监听Fragment生命周期原理
-
针对support包(或androidx包)下的fragment
其实监听Fragment生命周期也可以像Activity一样,给Fragment添加一个空的Fragment接口即可(很久以前看Glide源码是这么实现的)
但是Lifecycle并不是这么实现的,而是直接在Fragment源码层做了深度集成
public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener, LifecycleOwner, ViewModelStoreOwner { void performCreate(Bundle savedInstanceState) { ... mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE); } void performStart() { ... mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START); } void performResume() { ... mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME); } void performPause() { mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE); ... } void performStop() { mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP); ... } void performDestroy() { mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY); ... } }可见
Fragment在源码层 调用了handleLifecycleEvent方法,并实现了LifecycleOwner接口; 让我们非常方便的使用Lifecycle监听Fragment生命周期 -
针对app包下的Fragment
不好意思,
google并没有对app包下的Fragment做任何处理,方便开发者使用Lifecycle监听生命周期, 其所有的功能都需要自己手动实现(就像上面的example一样)同时
google已经标示app包下的Fragment为过期,不推荐使用了;而是推荐使用support包(或androidx包)下的Fragment了