一、前言
众所周知,Activity、Fragment中都有生命周期,如果生命周期管理不好,可能存在着内存泄漏,而有些第三方库又需要在每个生命周期方法中处理对应的事物,比如播放器mediaPlay、海康摄像头、地图、定位、Handle等等需要在生命周期里面进行管理和释放,代码管理又比较麻烦 Android官方似乎也注意到了这一点,因此在Google IO 2018大会上,推出了Android Jetpack开发工具包,其中就包含了一个非常重要的生命周期组件,即本篇的主角-Lifecycle
有了Lifecycle,再也不用担心生命周期同步问题
二、Lifecycle是什么?
Lifecycle是一个生命周期感知组件,一般用来响应Activity、Fragment等组件的生命周期变化,并将变化通知到已注册的观察者。有助于更好地组织代码,让代码逻辑符合生命周期规范,减少内存泄漏,增强稳定性。
在 Android 框架中定义的大多数应用组件都存在生命周期。生命周期由操作系统或进程中运行的框架代码管理。它们是 Android 工作原理的核心,应用必须遵循它们。如果不这样做,可能会引发内存泄漏甚至应用崩溃。
Lifecycle已经纳入新版本的AppCompatActivity和Fragment中了,并且Lifecycle还是Android Jetpack中其他两个组件LiveData和ViewModel的基础,意味着这个库可能将持续伴随着我们后续的开发,因此有什么理由不学习一番呢?
三、Lifecycle使用
lifecycle-extensions 中的 API 已弃用。您可以为特定 Lifecycle 工件添加所需的依赖项。
1、添加依赖
Kotlin
dependencies {
val lifecycle_version = "2.4.0-alpha02"
val 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")
// alternately - if using Java8, use the following instead of lifecycle-compiler
implementation("androidx.lifecycle:lifecycle-common-java8:$lifecycle_version")
// optional - helpers for implementing LifecycleOwner in a Service
implementation("androidx.lifecycle:lifecycle-service:$lifecycle_version")
// optional - ProcessLifecycleOwner provides a lifecycle for the whole application process
implementation("androidx.lifecycle:lifecycle-process:$lifecycle_version")
// optional - ReactiveStreams support for LiveData
implementation("androidx.lifecycle:lifecycle-reactivestreams-ktx:$lifecycle_version")
// optional - Test helpers for LiveData
testImplementation("androidx.arch.core:core-testing:$arch_version")
}
Java
dependencies {
val lifecycle_version = "2.4.0-alpha02"
val arch_version = "2.1.0"
// ViewModel
implementation("androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version")
// LiveData
implementation("androidx.lifecycle:lifecycle-livedata:$lifecycle_version")
// Lifecycles only (without ViewModel or LiveData)
implementation("androidx.lifecycle:lifecycle-runtime:$lifecycle_version")
// Saved state module for ViewModel
implementation("androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version")
// Annotation processor
annotationProcessor("androidx.lifecycle:lifecycle-compiler:$lifecycle_version")
// alternately - if using Java8, use the following instead of lifecycle-compiler
implementation("androidx.lifecycle:lifecycle-common-java8:$lifecycle_version")
// optional - helpers for implementing LifecycleOwner in a Service
implementation("androidx.lifecycle:lifecycle-service:$lifecycle_version")
// optional - ProcessLifecycleOwner provides a lifecycle for the whole application process
implementation("androidx.lifecycle:lifecycle-process:$lifecycle_version")
// optional - ReactiveStreams support for LiveData
implementation("androidx.lifecycle:lifecycle-reactivestreams:$lifecycle_version")
// optional - Test helpers for LiveData
testImplementation("androidx.arch.core:core-testing:$arch_version")
}
2、创建Observer
class AppLifecycleListener : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
public fun connectOnCreate(){
System.out.println("connectOnCreate================")
}
@OnLifecycleEvent(Lifecycle.Event.ON_START)
public fun connectOnStart(){
System.out.println("connectOnStart================")
}
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
public fun connectOnResume(){
System.out.println("connectOnResume================")
}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
public fun connectOnPause(){
System.out.println("connectOnPause================")
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
public fun connectOnStop(){
System.out.println("connectOnStop================")
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
public fun connectOnDestroy(){
System.out.println("connectOnDestroy================")
}
3、绑定Observer
class MainActivity : AppCompatActivity(), LifecycleOwner {
private lateinit var appLifecycleListener: AppLifecycleListener
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
appLifecycleListener = AppLifecycleListener()
lifecycle.addObserver(appLifecycleListener)
}
}
4、具体案例
Lifecycle使用之前的写法( 官方是java代码)
public class MainActivity extends Activity {
MapView mMapView = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//获取地图控件引用
mMapView = (MapView) findViewById(R.id.map);
//在activity执行onCreate时执行mMapView.onCreate(savedInstanceState),创建地图
mMapView.onCreate(savedInstanceState);
}
@Override
protected void onDestroy() {
super.onDestroy();
//在activity执行onDestroy时执行mMapView.onDestroy(),销毁地图
mMapView.onDestroy();
}
@Override
protected void onResume() {
super.onResume();
//在activity执行onResume时执行mMapView.onResume (),重新绘制加载地图
mMapView.onResume();
}
@Override
protected void onPause() {
super.onPause();
//在activity执行onPause时执行mMapView.onPause (),暂停地图的绘制
mMapView.onPause();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
//在activity执行onSaveInstanceState时执行mMapView.onSaveInstanceState (outState),保存地图当前的状态
mMapView.onSaveInstanceState(outState);
}
}
Lifecycle使用之后(kotlin)
一句代码就可完成,是不是so easy(没有处理onSaveInstanceState方法)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
lifecycle.addObserver(MapLifecycle(mapView, savedInstanceState))
}
- MapLifecycle
class MapLifecycle(private val mMapView: MapView, val savedInstanceState: Bundle?) : LifecycleObserver {
//如果只是activity中使用,这个方法可以onCreate()中,本人是Fragment中也复用了此方法,所以没写在onCreate()中
init {
mMapView.onCreate(savedInstanceState)
LogUtil.e("MapLifecycle---------init()")
//可以初始化地图样式风格等等
initMap()
}
private fun initMap() {
val aMap = mMapView.map
aMap.apply {
myLocationStyle = MyLocationStyle().apply {
// 设置定位的类型为 跟随模式
myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER)
// 自定义定位蓝点图标
// myLocationIcon(BitmapDescriptorFactory.fromResource(R.mipmap.ic_map_loction))
// 自定义精度范围的圆形边框颜色
strokeColor(Color.alpha(0))
//自定义精度范围的圆形边框宽度
strokeWidth(1f)
// 设置圆形的填充颜色
radiusFillColor(Color.argb(0, 0, 0, 0))
}
isMyLocationEnabled = false// 设置为true表示显示定位层并可触发定位,false表示隐藏定位层并不可触发定位,默认是false
// setOnMyLocationChangeListener(this)//设置SDK 自带定位消息监听
uiSettings.apply {
isMyLocationButtonEnabled = false//设置默认定位按钮是否显示,非必需设置。
isZoomControlsEnabled = false//是否允许显示缩放按钮
isRotateGesturesEnabled = false//不要旋转,防止mark角度和路径不对齐
}
moveCamera(CameraUpdateFactory.zoomTo(17f)) //设置缩放级别 地图的缩放级别一共分为 17 级,从 3 到 19。数字越大,展示的图面信息越精细。
}
}
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
fun onCreate() {
LogUtil.e("MapLifecycle---------onCreate()")
}
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
fun onResume() {
mMapView.onResume()
LogUtil.e("MapLifecycle---------onResume()")
}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
fun onPause() {
mMapView.onPause()
LogUtil.e("MapLifecycle---------onPause()")
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun onDestroy() {
mMapView.onDestroy()
LogUtil.e("MapLifecycle---------onDestroy()")
}
}
四、Lifecycle源码分析
Lifecycle 是一个类,用于存储有关组件(如 Activity 或 Fragment)的生命周期状态的信息,并允许其他对象观察此状态。
Lifecycle 使用两种主要枚举跟踪其关联组件的生命周期状态: Lifecycle类
ublic abstract class Lifecycle {
//添加观察者
@MainThread
public abstract void addObserver(@NonNull LifecycleObserver observer);
//移除观察者
@MainThread
public abstract void removeObserver(@NonNull LifecycleObserver observer);
//获取当前状态
public abstract State getCurrentState();
//生命周期事件,对应Activity生命周期方法
public enum Event {
ON_CREATE,
ON_START,
ON_RESUME,
ON_PAUSE,
ON_STOP,
ON_DESTROY,
ON_ANY //可以响应任意一个事件
}
//生命周期状态. (Event是进入这种状态的事件)
public enum State {
DESTROYED,
INITIALIZED,
CREATED,
STARTED,
RESUMED;
//判断至少是某一状态
public boolean isAtLeast(@NonNull State state) {
return compareTo(state) >= 0;
}
}
Lifecycle 使用两种主要枚举跟踪其关联组件的生命周期状态:
Event,生命周期事件,这些事件对应Activity/Fragment生命周期方法。
State,生命周期状态,而Event是指进入一种状态的事件。
Event触发的时机:
ON_CREATE、ON_START、ON_RESUME事件,是在LifecycleOwner对应的方法执行 之后 分发。
ON_PAUSE、ON_STOP、ON_DESTROY事件,是在LifecycleOwner对应的方法调用 之前 分发。
这保证了LifecycleOwner是在这个状态内。
官网有个图很清晰:
先从使用上说起
class LifecycleDemoActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 省略其他代码...
lifecycle.addObserver(myLocationListener)
}
}
==AppCompatActivity== 继承关系:
androidx.appcompat.app.AppCompatActivity
-> androidx.fragment.app.FragmentActivity
-> androidx.activity.ComponentActivity
-> androidx.core.app.ComponentActivity
-> android.app.Activity
lifecycle 就是在 androidx.activity.ComponentActivity 定义的:
public class ComponentActivity extends androidx.core.app.ComponentActivity implements
LifecycleOwner,
ViewModelStoreOwner,
HasDefaultViewModelProviderFactory,
SavedStateRegistryOwner,
OnBackPressedDispatcherOwner {
// 省略其他代码...
private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
@NonNull
@Override
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
}
也就是说 lifecycle 就是 LifecycleRegistry,那我们就来看看 ==LifecycleRegistry.addObserver== 方法:
public class LifecycleRegistry extends Lifecycle {
// 省略其他代码...
@Override
public void addObserver(@NonNull LifecycleObserver observer) {
// 初始状态
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
// 封装 observer 和 initialState
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
// 将封装后的对象放进 Map 当中
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
//...
if (!isReentrance) {
// 核心方法
sync();
}
}
}
private void sync() {
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null) {
throw new IllegalStateException("LifecycleOwner of this LifecycleRegistry is already"
+ "garbage collected. It is too late to change lifecycle state.");
}
while (!isSynced()) {
mNewEventOccurred = false;
// no need to check eldest for nullability, because isSynced does it for us.
if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
backwardPass(lifecycleOwner);
}
Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
if (!mNewEventOccurred && newest != null
&& mState.compareTo(newest.getValue().mState) > 0) {
forwardPass(lifecycleOwner);
}
}
mNewEventOccurred = false;
}
可以看出 init 和 destroy 状态是在 create、start、resume 状态之前的。
-
backwardPass 方法用于 “向后传递”,例如屏幕旋转或关闭页面的情况,在关闭页面之前的状态是 resume,那么关闭页面后,就要依次执行 onPause、onStop、onDestroy,对照上面的图来看,有一种 “往回走” 的感觉,所以叫做 backwardPass
-
forwardPass 方法用于 “向前传递”,比如打开一个新页面,会执行 onCreate、onStart、onResume,对照上面的图来看,就是一直往前走的感觉,所以叫做 forwardPass
ReportFragment
我们再看看新版AppCompatActivity是如何将事件分发给LifecycleRegistry的,还记得SupportActivity中有这么一段逻辑吗:
public class SupportActivity extends Activity implements LifecycleOwner {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ReportFragment.injectIfNeededIn(this);
}
}
public class ReportFragment extends Fragment {
public static void injectIfNeededIn(Activity activity) {
android.app.FragmentManager manager = activity.getFragmentManager();
if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
manager.executePendingTransactions();
}
}
@Override
public void onStart() {
super.onStart();
dispatchStart(mProcessListener);
dispatch(Lifecycle.Event.ON_START);
}
// ...... 其他生命周期也是同样调用了dispatch(Lifecycle.Event.xxx)分发事件
@Override
public void onPause() {
super.onPause();
dispatch(Lifecycle.Event.ON_PAUSE);
}
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);
}
}
}
}
可以看到,SupportActivity添加了一个没有页面的ReportFragment,在ReportFragment的生命周期函数中,调用了LifecycleRegistry.handleLifecycleEvent()方法来分发生命周期事件。用一张图总结一下就是:
AppCompatActivity中添加了一个ReportFragment,其生命周期变化时,调用LifecycleRegistry.handleLifecycleEvent()方法通知LifecycleRegistry改变状态,LifecycleRegistry内部调用moveToState()改变状态,并调用每个LifecycleObserver.onStateChange()方法通知生命周期变化。
- 为什么不直接在SupportActivity的生命周期函数中给Lifecycle分发生命周期事件,而是要加一个Fragment呢?
因为不是所有的页面都继承AppCompatActivity,为了兼容非AppCompatActivity,所以封装一个同样具有生命周期的Fragment来给Lifecycle分发生命周期事件。