Android Jetpack 架构组件之 Lifecycle (一)起源

Lifecycle的存在乎义

文章开头先来引入一个 业务案例安全

这是一个学习英语的App,部分页面支持 划词播放markdown

如何能够优雅得实现这个真实的业务场景呢?架构

首先须要定义一个全局单例的播放器,播放器有一个方法play(val content: String)ide

object ContentPlayer {
    
    fun play(content: String) {
        //调用系统播放器播放 
    }
    
    fun prepare(context: Context) {
        //播放器的准备工做
    }
}
复制代码

实现ContentPlayer以后,就能够在支持划词播放功能的Activity的划词事件回调中这样写:post

class ContentActivity : AppCompatActivity(), UnderLineWordCallBack {
    
    override fun onCreate(savedInstanceState: Bundle?) {
        ...
        ContentPlayer.prepare(this)
    }
    
	//当前Activity的划词播放后回调这里
    override fun callback(content: String) {
    	// 开始播放
        ContentPlayer.play(content)
    }

}
复制代码

这样这个功能就作完了。真得作完了吗?若是你的Leader看到这样的代码,怕不是次日让你卷铺盖走人~(开玩笑的开玩笑的)学习

这样的代码可能会发生 内存泄漏
假设客户划了一段很长的英语文章,而后点击播放,播放到一半客户不想听了,直接点击了返回键后,播放器还持有着 ContentActivity的引用,在播放器继续播放的过程当中,ContentActivity是没法被gc的,这就会出现了问题优化

因此咱们还须要准备一个unAttach()方法。最终的方案以下:this

object ContentPlayer{

    fun play(content: String) {
        //调用系统播放器播放
    }

    fun prepare(context: Context) {
        //播放器的准备工做
    }
    
    fun unAttach() {
        //释放当前持有的Activity资源 
    }
}
复制代码
class ContentActivity : AppCompatActivity(), UnderLineWordCallBack {
    
    override fun onCreate(savedInstanceState: Bundle?) {
        ...
        //准备播放器资源
        ContentPlayer.prepare(this)
    }
    
	//当前Activity的划词播放后回调这里
    override fun callback(content: String) {
    	// 开始播放
        ContentPlayer.play(content)
    }
    
    override fun onDestory() {
        ...
        // 释放资源
        ContentPlayer.unAttach()
    }

}
复制代码

上面这样的代码固然没有问题了,能够正常使用,咱们还严谨的保护了App不发生内存泄漏,值得表扬!spa

可是还有问题:code

  • 没法保证调用一致性,在多人协做开发时存在很大的隐患
  • 调用不够优雅
  • 代码侵入型太强

若是当前App有不少的Activity要用到划词播放这个功能,那么咱们就须要在每个Activity中重复上面的代码,当代码量上来以后,会很容易遗忘调用unAttach方法,并且一个项目不多是以后一我的完成,每每是协做开发,若是别人写的界面想要调用你写的ContentPlayer,除非你写了很详细的注释,不然必须深刻源码,才知道在Activity的onDestory处去释放资源。

更优雅,更安全的写法,就是利用Lifecycle组件

Lifecycle的出现如何解决问题

在进一步使用Lifecycle优化上述代码以前,先看一下Lifecycle的官方定义:

生命周期感知型组件可执行操做来响应另外一个组件(如 Activity 和 Fragment)的生命周期状态的变化。这些组件有助于您写出更有条理且每每更精简的代码,这样的代码更易于维护。

也就是说,咱们写代码中开发的某个组件须要去感知生命周期时,要首先想到使用Lifecycle。

可让咱们在组件内部来监听到生命周期,就像这样:

object ContentPlayer : LifecycleObserver{

    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    fun prepare(context: Context) {
        //播放器的准备工做
    }
    
    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    fun unAttach() {
        //释放当前持有的Activity资源
    }
}
复制代码

经过方法注解,决定当前方法被调用的时机。以后在须要使用ContentPlayer的Activity中去注册观察者

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 一行代码搞定
        lifecycle.addObserver(ContentPlayer)
    }
复制代码

用到划词播放的界面只需经过一行代码,lifecycle.addObserver(ContentPlayer)注册lifecycle观察者。完美解决了调用一致性和代码侵入性太强的问题。

Lifecycle给其余Jectpack相关组件铺路

Lifecycle除了给咱们开发者使用以外,在Android源码很 Lifecycle组件是Google Jectpack架构的基础,Jectpack的组件:databing、viewmodel等等都依赖于lifecycle对生命周期的感知,因此我认为在学习jectpack和MVVM以前,须要先了解一下Lifecycle的使用和 基本实现原理