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

Lifecycle的存在意义

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

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

如何可以优雅得实现这个真实的业务场景呢?

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

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

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

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,992评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,212评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,535评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,197评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,310评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,383评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,409评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,191评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,621评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,910评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,084评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,763评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,403评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,083评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,318评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,946评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,967评论 2 351