Lifecycle
是google
提供的一个能够监听activity
、fragment
、service
、app process
生命周期的组件库html
咱们最经常使用的是监听activity
和fragment
生命周期,好比使用MVP
架构,Presenter
通常须要在activity
的oncreate
方法中初始化变量和资源等,在ondestory
中释放资源等android
若是咱们不用Lifecycle
组件的写法是这样的,必须手动在activity
的onCreate
和onDestroy
方法调presenter对应的方法git
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()
}
...
}
复制代码
很显然 这样很是不优雅github
那咱们该如何使用Lifecycle
组件库呢?bash
下面主要以Presenter
为Example讲解架构
先定义一个ActivityPresenter
app
// 先定义一个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
代码实现以下:ide
// 注意实现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
}
}
复制代码
可见步骤以下:post
LifecycleObserver
接口(好比:BasePresenter)@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
}
}
复制代码
对于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包下的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生命周期的需求不多,可是咱们仍是能够了解一下
同理 若是咱们手动实现的话,同样须要先实现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先后台切换的方法以下:
监听全部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组件库是怎么监听activity、fragment生命周期的呢?
若是咱们不用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生命周期原理
针对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
了