Android Jetpack系列之Lifecycle
Posted 冬天的毛毛雨
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android Jetpack系列之Lifecycle相关的知识,希望对你有一定的参考价值。
Lifecycle介绍
Lifecycle
可以让某一个类变成Activity
、Fragment
的生命周期观察者类,监听其生命周期的变化并可以做出响应。Lifecycle
使得代码更有条理性、精简、易于维护。
Lifecycle中主要有两个角色:
- LifecycleOwner: 生命周期拥有者,如Activity/Fragment等类都实现了该接口并通过getLifecycle()获得Lifecycle,进而可通过addObserver()添加观察者。
- LifecycleObserver: 生命周期观察者,实现该接口后就可以添加到Lifecycle中,从而在被观察者类生命周期发生改变时能马上收到通知。
实现LifecycleOwner
的生命周期拥有者可与实现LifecycleObserver
的观察者完美配合。
场景case
假设我们有一个在屏幕上显示设备位置的 Activity,我们可能会像下面这样实现:
internal class MyLocationListener(
private val context: Context,
private val callback: (Location) -> Unit) {
fun start() {
// connect to system location service
}
fun stop() {
// disconnect from system location service
}
}
class MyActivity : AppCompatActivity() {
private lateinit var myLocationListener: MyLocationListener
override fun onCreate(...) {
myLocationListener = MyLocationListener(this) { location ->
// update UI
}
}
public override fun onStart() {
super.onStart()
myLocationListener.start()
// manage other components that need to respond
// to the activity lifecycle
}
public override fun onStop() {
super.onStop()
myLocationListener.stop()
// manage other components that need to respond
// to the activity lifecycle
}
}
注:上面代码来自官方示例
~
我们可以在Activity
或 Fragment
的生命周期方法(示例中的onStart/onStop
)中直接对依赖组件进行操作。但是,这样会导致代码条理性很差且不易扩展。那么有了Lifecycle
,可以将依赖组件的代码从Activity/Fragment
生命周期方法中移入组件本身中。
Lifecycle使用
根目录下build.gradle:
allprojects {
repositories {
google()
// Gradle小于4.1时,使用下面的声明替换:
// maven {
// url 'https://maven.google.com'
// }
// An alternative URL is 'https://dl.google.com/dl/android/maven2/'
}
}
app下的build.gradle:
dependencies {
def lifecycle_version = "2.3.1"
def arch_version = "2.1.0"
// ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
// LiveData
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
// Lifecycles only (without ViewModel or LiveData)
implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version"
// Saved state module for ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version"
// Annotation processor
kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
// 可选 - 如果使用Java8,使用下面这个代替lifecycle-compiler
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
// 可选 - 在Service中使用Lifecycle
implementation "androidx.lifecycle:lifecycle-service:$lifecycle_version"
// 可选 - Application中使用Lifecycle
implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version"
// 可选 - ReactiveStreams support for LiveData
implementation "androidx.lifecycle:lifecycle-reactivestreams-ktx:$lifecycle_version"
// 可选 - Test helpers for LiveData
testImplementation "androidx.arch.core:core-testing:$arch_version"
}
Activity/Fragment中使用Lifecycle
首先先来实现LifecycleObserver
观察者:
open class MyLifeCycleObserver : LifecycleObserver {
@OnLifecycleEvent(value = Lifecycle.Event.ON_START)
fun connect(owner: LifecycleOwner) {
Log.e(JConsts.LIFE_TAG, "Lifecycle.Event.ON_CREATE:connect")
}
@OnLifecycleEvent(value = Lifecycle.Event.ON_STOP)
fun disConnect() {
Log.e(JConsts.LIFE_TAG, "Lifecycle.Event.ON_DESTROY:disConnect")
}
}
在方法上,我们使用了@OnLifecycleEvent
注解,并传入了一种生命周期事件,其类型可以为ON_CREATE
、ON_START
、ON_RESUME
、ON_PAUSE
、ON_STOP
、ON_DESTROY
、ON_ANY
中的一种。其中前6个对应Activity中对应生命周期的回调,最后一个ON_ANY可以匹配任何生命周期回调。 所以,上述代码中的connect()、disConnect()
方法分别应该在Activity
的onStart()、onStop()
中触发时执行。接着来实现我们的Activity
:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Log.e(JConsts.LIFE_TAG, "$ACTIVITY:onCreate")
//添加LifecycleObserver观察者
lifecycle.addObserver(MyLifeCycleObserver())
}
override fun onStart() {
Log.e(JConsts.LIFE_TAG, "$ACTIVITY:onStart")
super.onStart()
}
override fun onResume() {
Log.e(JConsts.LIFE_TAG, "$ACTIVITY:onResume")
super.onResume()
}
override fun onPause() {
Log.e(JConsts.LIFE_TAG, "$ACTIVITY:onPause")
super.onPause()
}
override fun onStop() {
Log.e(JConsts.LIFE_TAG, "$ACTIVITY:onStop")
super.onStop()
}
override fun onDestroy() {
Log.e(JConsts.LIFE_TAG, "$ACTIVITY:onDestroy")
super.onDestroy()
}
}
可以看到在Activity中我们只是在onCreate()中添加了这么一行代码:
lifecycle.addObserver(MyLifeCycleObserver())
其中getLifecycle()
是LifecycleOwner
中的方法,返回的是Lifecycle
对象,并通过addObserver()
的方式添加了我们的生命周期观察者。接下来看执行结果,启动Activity
:
2021-06-30 20:57:58.038 11257-11257/ E/Lifecycle_Study: ACTIVITY:onCreate
//onStart() 传递到 MyLifeCycleObserver: connect()
2021-06-30 20:57:58.048 11257-11257/ E/Lifecycle_Study: ACTIVITY:onStart
2021-06-30 20:57:58.049 11257-11257/ E/Lifecycle_Study: Lifecycle.Event.ON_START:connect
2021-06-30 20:57:58.057 11257-11257/ E/Lifecycle_Study: ACTIVITY:onResume
关闭Activity:
2021-06-30 20:58:02.646 11257-11257/ E/Lifecycle_Study: ACTIVITY:onPause
//onStop() 传递到 MyLifeCycleObserver: disConnect()
2021-06-30 20:58:03.149 11257-11257/ E/Lifecycle_Study: ACTIVITY:onStop
2021-06-30 20:58:03.161 11257-11257/ E/Lifecycle_Study: Lifecycle.Event.ON_STOP:disConnect
2021-06-30 20:58:03.169 11257-11257/ E/Lifecycle_Study: ACTIVITY:onDestroy
可以看到我们的MyLifeCycleObserver
中的connect()/disconnect()
方法的确是分别在Activity
的onStart()/onStop()
回调时执行的。
自定义LifecycleOwner
在AndroidX
中的Activity、Fragmen
实现了LifecycleOwner
,通过getLifecycle()
能获取到Lifecycle
实例(Lifecycle
是抽象类,实例化的是子类LifecycleRegistry
)。
public interface LifecycleOwner {
@NonNull
Lifecycle getLifecycle();
}
public class LifecycleRegistry extends Lifecycle {
}
如果我们想让一个自定义类成为LifecycleOwner
,可以直接实现LifecycleOwner
:
class CustomLifeCycleOwner : LifecycleOwner {
private lateinit var registry: LifecycleRegistry
fun init() {
registry = LifecycleRegistry(this)
//通过setCurrentState来完成生命周期的传递
registry.currentState = Lifecycle.State.CREATED
}
fun onStart() {
registry.currentState = Lifecycle.State.STARTED
}
fun onResume() {
registry.currentState = Lifecycle.State.RESUMED
}
fun onPause() {
registry.currentState = Lifecycle.State.STARTED
}
fun onStop() {
registry.currentState = Lifecycle.State.CREATED
}
fun onDestroy() {
registry.currentState = Lifecycle.State.DESTROYED
}
override fun getLifecycle(): Lifecycle {
//返回LifecycleRegistry实例
return registry
}
}
首先我们的自定义类实现了接口LifecycleOwner
,并在getLifecycle()
返回LifecycleRegistry
实例,接下来就可以通过LifecycleRegistry#setCurrentState
来传递生命周期状态了。到目前为止,已经完成了大部分工作,最后也是需要去添加LifecycleObserver
:
//注意:这里继承的是Activity,本身并不具备LifecycleOwner能力
class MainActivity : Activity() {
val owner: CustomLifeCycleOwner = CustomLifeCycleOwner()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Log.e(JConsts.LIFE_TAG, "$ACTIVITY:onCreate")
//自定义LifecycleOwner
owner.init()
//添加LifecycleObserver
owner.lifecycle.addObserver(MyLifeCycleObserver())
}
override fun onStart() {
Log.e(JConsts.LIFE_TAG, "$ACTIVITY:onStart")
super.onStart()
owner.onStart()
}
override fun onResume() {
Log.e(JConsts.LIFE_TAG, "$ACTIVITY:onResume")
super.onResume()
owner.onResume()
}
override fun onPause() {
Log.e(JConsts.LIFE_TAG, "$ACTIVITY:onPause")
super.onPause()
owner.onPause()
}
override fun onStop() {
Log.e(JConsts.LIFE_TAG, "$ACTIVITY:onStop")
super.onStop()
owner.onStop()
}
override fun onDestroy() {
Log.e(JConsts.LIFE_TAG, "$ACTIVITY:onDestroy")
super.onDestroy()
owner.onDestroy()
}
}
很简单,主要是在onCreate()
里实例化LifecycleOwner
并调用init()
完成LifecycleRegistry
实例化。接着跟androidX
中的Activity
一样了,通过getLifecycle()
得到LifecycleRegistry
实例并通过addObserver()
注册LifecycleObserver
,最后代码执行结果跟上面的结果一致,不再重复贴了。
Application中使用Lifecycle
首先记得要先引入对应依赖:
implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version"
然后代码编写如下:
//MyApplicationLifecycleObserver.kt
class MyApplicationLifecycleObserver : LifecycleObserver {
@OnLifecycleEvent(value = Lifecycle.Event.ON_START)
fun onAppForeground() {
Log.e(JConsts.LIFE_APPLICATION_TAG, "onAppForeground")
}
@OnLifecycleEvent(value = Lifecycle.Event.ON_STOP)
fun onAppBackground() {
Log.e(JConsts.LIFE_APPLICATION_TAG, "onAppBackground")
}
}
//MyApplication.kt
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
ProcessLifecycleOwner.get().lifecycle.addObserver(MyApplicationLifecycleObserver())
}
}
//manifest.xml
<application
android:name=".MyApplication">
</application>
启动应用:
2021-06-30 21:55:11.657 14292-14292/ E/Lifecycle_App_Study: onAppForeground
点击Home键,应用切到后台:
2021-06-30 21:55:35.741 14292-14292/ E/Lifecycle_App_Study: onAppBackground
再切回来:
2021-06-30 21:55:11.657 14292-14292/ E/Lifecycle_App_Study: onAppForeground
ProcessLifecycleOwner
可以很方便地帮助我们检测App前后台状态。
Service中使用Lifecycle
在Service
中使用Lifecycle
同样需要先引入依赖:
implementation "androidx.lifecycle:lifecycle-service:$lifecycle_version"
然后继承LifecycleService
:
//MyService.kt
class MyService : LifecycleService() {
override fun onCreate() {
Log.e(JConsts.SERVICE, "Service:onCreate")
super.onCreate()
lifecycle.addObserver(MyLifeCycleObserver())
}
override fun onStart(intent: Intent?, startId: Int) {
Log.e(JConsts.SERVICE, "Service:onStart")
super.onStart(intent, startId)
}
override fun onDestroy() {
Log.e(JConsts.SERVICE, "Service:onDestroy")
super.onDestroy()
}
}
//MainActivity.kt
/**
* 启动Service
*/
private fun startLifecycleService() {
val intent = Intent(this, MyService::class.java)
startService(intent)
}
/**
* 关闭Service
*/
fun closeService(view: View) {
val intent = Intent(this, MyService::class.java)
stopService(intent)
}
LifecycleService
中实现了LifecycleOwner
接口,所以子类中可以直接通过getLifecycle()
添加生命周期Observer
,在Activity
中启动Service
:
2021-07-01 14:10:09.703 7606-7606/ E/SERVICE: Service:onCreate
2021-07-01 14:10:09.709 7606-7606/ E/SERVICE: Service:onStart
2021-07-01 14:10:09.712 7606-7606/ E/SERVICE: Lifecycle.Event.ON_START:connect
操作停止Service:
2021-07-01 14:10:13.062 7606-7606/ E/SERVICE: Service:onDestroy
2021-07-01 14:10:13.063 7606-7606/ E/SERVICE: Lifecycle.Event.ON_STOP:disConnect
结果也很简单,这里注意一点:因为Service
中没有onPause/onStop
状态,所以在Service#onDestroy()
之后,LifecycleService
里会同时分发Lifecycle.Event.ON_STOP、Lifecycle.Event.ON_DESTROY
两个Event
,所以我们的观察者监听哪个都是可以的。
完整代码地址
完整代码地址参见:Jetpack Lifecycle例子
源码解析
Lifecycle.java
public abstract class Lifecycle {
@NonNull
AtomicReference<Object> mInternalScopeRef = new AtomicReference<>();
@MainThread
public abstract void addObserver(@NonNull LifecycleObserver observer);
@MainThread
public abstract void removeObserver(@NonNull LifecycleObserver observer);
@MainThread
@NonNull
public abstract State getCurrentState();
//生命周期事件 对应于Activity/Fragment生命周期
public enum Event {
ON_CREATE,
ON_START,
ON_RESUME,
ON_PAUSE,
ON_STOP,
ON_DESTROY,
/**
* An constant that can be used to match all events.
*/
ON_ANY
}
//生命周期状态
public enum State {
//onStop()之后,此状态是LifecycleOwner终态,Lifecycle不在分发Event
DESTROYED,
//初始化状态
INITIALIZED,
//onCreate()或onStop()之后
CREATED,
//onStart()或onPause()之后
STARTED,
//onResume()之后
RESUMED;
public boolean isAtLeast(@NonNull State state) {
return compareTo(state) >= 0;
}
}
}
Lifecycle
中的两个重要枚举:
- Event:生命周期事件,包括
ON_CREATE
、ON_START
、ON_RESUME
、ON_PAUSE
、ON_STOP
、ON_DESTROY
、ON_ANY
,对应于Activity/Fragment
生命周期。 - State:生命周期状态,包括
DESTROYED
、INITIALIZED
、CREATED
、STARTED
、RESUMED
,Event
的改变会使得State
也发生改变。
两者关系如下:
Event生命周期事件分发&接收
我们的Activity
继承自AppCompatActivity
,继续往上找AppCompatActivity
的父类,最终能找到了ComponentActivity
:
public class ComponentActivity extends androidx.core.app.ComponentActivity implements LifecycleOwner{
//省略其他代码 只显示Lifecycle相关代码
private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//将生命周期的事件传递交给ReportFragment
ReportFragment.injectIfNeededIn(this);
if (mContentLayoutId != 0) {
setContentView(mContentLayoutId);
}
}
}
@CallSuper
@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
Lifecycle lifecycle = getLifecycle();
if (lifecycle instanceof LifecycleRegistry) {
((LifecycleRegistry) lifecycle).setCurrentState(Lifecycle.State.CREATED);
}
super.onSaveInstanceState(outState);
mSavedStateRegistryController.performSave(outState);
}
@NonNull
@Override
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
}
可以看到getLifecycle()
返回的是LifecycleRegistry
实例,并且在onSaveInstanceState()
中分发了Lifecycle.State.CREATED
状态,但是其他生命周期回调中并没有写了呀,嗯哼?再细看一下,onCreate()
中有个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) {
if (Build.VERSION.SDK_INT >= 29) {
activity.registerActivityLifecycleCallbacks(
new LifecycleCallbacks());
}
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();
}
}
@SuppressWarnings("deprecation")
static void dispatch(@NonNull Activity activity, @NonNull Lifecycle.Event event) {
//已经被标注为@Deprecated
if (activity instanceof LifecycleRegistryOwner) {
((LifecycleRegi以上是关于Android Jetpack系列之Lifecycle的主要内容,如果未能解决你的问题,请参考以下文章
Android Jetpack系列 之 WorkManager