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

本文探讨了在Android开发中如何避免因播放器持有Activity引用导致的内存泄漏问题。通过创建一个ContentPlayer对象,并利用Lifecycle组件,实现对Activity生命周期的监听,确保在Activity销毁时自动释放资源。此外,还指出传统做法在多人协作和代码一致性方面的不足,并介绍了Lifecycle如何提供更优雅、安全的解决方案,减少代码侵入性并提高调用一致性。

此事件回调中这样写:

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()方法。最终的方案如下:

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不发生内存泄漏,值得表扬!

但是还有问题:

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

如果当前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的使用和 基本实现原理

底层原理+项目实战+面试专题

点击即可领取 Android进阶、架构设计、NDK、跨平台、底层源码,面试资料,Flutter源码解析资料

(包含Android技能图谱+开源框架源码+视频解析+大厂面试题)

评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值