Jetpack练手(04):Lifecycle

   日期:2020-09-05     浏览:99    评论:0    
核心提示:文章目录一、搭建布局二、非 Lifecycle 实现三、Lifecycle 实现一、搭建布局新建 LifecycleDemo 工程实现 界面停留时间计数,在 activity_main.xml 搭建简单布局(省略属性),如下:

文章目录

  • 一、搭建布局
  • 二、非 Lifecycle 实现
  • 三、Lifecycle 实现
  • 四、Demo 效果

一、搭建布局

新建 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()
    }
}

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

系统启动 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14
SystemClock.elapsedRealtime() 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14
① Activity onResume
① chronometer.base 03
② elapsedTime 0 1 2 3 4
② Activity onPause !!
  1. 在系统启动 3s 后启动 Activity,此时设置 Chronometerbase 为当前系统启动后经过的时间,即 3s
  2. Activity 前台运行 4s 后退到后台,此时经过的时间 elapsedTime = SystemClock.elapsedRealtime() - chronometer.base,即 7 - 3 = 4s
系统启动 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14
SystemClock.elapsedRealtime() 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14
① Activity onResume
② elapsedTime 0 1 2 3 4
② chronometer.base 03 05
  1. Activity 退到后台之后又经过 2sSystemClock.elapsedRealtime() 走到了 9s,此时将 Activity 拉起到前台;
  2. 要保证计时器数字不变,需要调整它的 base 与当前系统经过时间的差值不变,即调整 base5schronometer.base = SystemClock.elapsedRealtime() - elapsedTime,即 9 - 4 = 5s
系统启动 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14
SystemClock.elapsedRealtime() 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14
① chronometer.base 05
① elapsedTime 0 1 2 3 4 5 6 7 8 9
  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 效果

效果如下:

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服