Jetpack全家桶(二)之Lifecycle使用及源码

569 阅读7分钟

一、前言

众所周知,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分发生命周期事件。