Jetpack练手(04):Lifecycle


一、搭建布局

新建 LifecycleDemo 工程实现 界面停留时间计时,在 activity_main.xml 搭建简单布局(省略属性),如下:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    tools:context=".MainActivity">

    <Chronometer
        android:id="@+id/chronometer" />

</androidx.constraintlayout.widget.ConstraintLayout>

仅有一个控件:

  1. chronometer - Chronometer,计时器。

整体布局如下:
在这里插入图片描述


二、非 Lifecycle 实现

MainActivity 类中,重写 onResume()onPause() 如下:

class MainActivity : AppCompatActivity() {

    private var elapsedTime: Long = 0L

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
    
    override fun onResume() {
        super.onResume()
        // 更新计时器 base 时间
        chronometer.base = SystemClock.elapsedRealtime() - elapsedTime
        chronometer.start()
    }

    override fun onPause() {
        super.onPause()
        // 记录 Activity onPause 时已经经过时间
        elapsedTime = SystemClock.elapsedRealtime() - chronometer.base
        chronometer.stop()
    }
}

可以举一个直观的例子理解一下:

系统启动000102030405060708091011121314
SystemClock.elapsedRealtime()000102030405060708091011121314
① Activity onResume
① chronometer.base03
② elapsedTime01234
② Activity onPause!!
  1. 在系统启动 3s 后启动 Activity,此时设置 Chronometerbase 为当前系统启动后经过的时间,即 3s
  2. Activity 前台运行 4s 后退到后台,此时经过的时间 elapsedTime = SystemClock.elapsedRealtime() - chronometer.base,即 7 - 3 = 4s
系统启动000102030405060708091011121314
SystemClock.elapsedRealtime()000102030405060708091011121314
① Activity onResume
② elapsedTime01234
② chronometer.base0305
  1. Activity 退到后台之后又经过 2sSystemClock.elapsedRealtime() 走到了 9s,此时将 Activity 拉起到前台;
  2. 要保证计时器数字不变,需要调整它的 base 与当前系统经过时间的差值不变,即调整 base5schronometer.base = SystemClock.elapsedRealtime() - elapsedTime,即 9 - 4 = 5s
系统启动000102030405060708091011121314
SystemClock.elapsedRealtime()000102030405060708091011121314
① chronometer.base05
① elapsedTime0123456789
  1. 此时 Activity 在前台,Chronometer 可以按照调整后的 base 正常计时。

效果如下:
在这里插入图片描述


三、Lifecycle 实现

上面示例看起来没什么问题,但在真实的应用中,会有很多界面管理和组件调用,在 onXXXX() 生命周期回调中放置大量的代码,会变得难以维护。因此需要以弹性和隔离的方式解决这些问题,Lifecycle 组件提供了这样的方式,所以可以尝试使用 Lifecycle 重新实现上面示例。

首先,自定义一个计时器控件 MyChronometer 继承自 Chronometer 并实现 LifecycleObserver 接口:

class MyChronometer @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : Chronometer(context, attrs, defStyleAttr), LifecycleObserver {}

通过向 MyChronometer 类中的方法添加注解来监控组件的生命周期状态,方法内具体逻辑和上面类似:

class MyChronometer @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : Chronometer(context, attrs, defStyleAttr), LifecycleObserver {

    private var elapsedTime: Long = 0L

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    private fun resumeChronometer() {
        base = SystemClock.elapsedRealtime() - elapsedTime
        start()
    }
    
    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    private fun pauseChronometer() {
        elapsedTime = SystemClock.elapsedRealtime() - base
        stop()
    }
}

修改 activity_main.xml 中使用自定义计时器控件 MyChronometer

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    tools:context=".MainActivity">

    <com.example.lifecycledemo.MyChronometer
        android:id="@+id/chronometer" />

</androidx.constraintlayout.widget.ConstraintLayout>

MainActivity 中通过调用 Lifecycle 类的 addObserver() 方法并传递观察者的实例来添加观察者:

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        lifecycle.addObserver(chronometer)
    }
}

四、Demo 效果

效果如下:
在这里插入图片描述


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值