感知生命周期 Lifecycles

  • 教程来源
  • 计时器
    • 计时器的常见方法
    • 前台计时,后台暂停的计时器
  • LifeCycles

教程来源

致谢B站良心Up主,教程地址戳这里

这次的例子我们将使用 “计时器” 控件来演示,先来了解一下计时器的用法。

计时器

计时器是属于 TextView 的子类,来到 Text 界面,直接将 TextView 改为 Chronometer 。

修改过后,界面便会出现一个时间,前面为分,后面是秒。我们将 id 改为 meter 。

计时器的常见方法

chronometer.setBase(SystemClock.elapsedRealtime()); //设置基准时间,并从该时间开始计数
// System.currentTimeMillis(); //(UNIX时间 自1970 1-1 到现在的毫秒数)
// SystemClock.elapsedRealtime(); //(系统启动到现在的时间,包含设备深度休眠的时间)
// SystemClock.uptimeMillis(); //(自系统启动时开始计数,毫秒为单位。从系统启动到现在,这个过程中的处于非休眠期的时间。当系统进入深度睡眠时(CPU关闭,设备变黑,等待外部输入装置)该时钟会停止)chronometer.getBase(); //获取当前设置的基准时间chronometer.setFormat("计时:%s"); //设置用于显示的格式化字符串(计时器将根据这个字符串来显示,替换字符串中第一个“%s”为当前"MM:SS"或 "H:MM:SS"格式的时间显示。)chronometer.setCountDown(true); //设置为倒计时模式chronometer.start(); //计时开始chronometer.stop(); //停止刷新计时UI更新

前台计时,后台暂停的计时器

来到 MainActivity.java:
一般我们都将系统基准时间设为 SystemClock.elapsedRealtime(),这个时间是手机从上一次启动到现在经过的毫秒数,它只与系统启动有关,较为可靠,并且不设置的话,默认就是用它。

如果我们直接设置了基准时间(setBase)后,就开始计时(start),那么即使软件进入了后台,计时器不会停止,依旧在计时

如果我们想要达到软件在前台计时,后台暂停的效果要怎么做呢?

生命周期中,当软件进入后台会默认调用 onPause(),
在这里,我们用变量 elapsedTime 保存下来了一个时间:
recordingTime = SystemClock.elapsedRealtime() - chronometer.getBase();
// 当前系统时间 - 启动计时器的时间 = 上次计时的持续时间
我们在进入后台前,保存了上次计时的持续时间。
那么在我们再次回到前台时,会调用 onResume(),
此时,我们重新设置了基准时间:
chronometer.setBase(SystemClock.elapsedRealtime() - recordingTime );
// 本该是从0开始,我们跳过已经记录的时间,达到继续计时的效果。

public class MainActivity extends AppCompatActivity {Chronometer chronometer;private long recordingTime ;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);chronometer = findViewById(R.id.meter);chronometer.setBase(SystemClock.elapsedRealtime()); // 手机从上一次启动到现在,经过时间的毫秒数,比较可靠,只与系统启动有关,不写就默认为此}@Overrideprotected void onPause() {super.onPause();recordingTime = SystemClock.elapsedRealtime() - chronometer.getBase(); // 当前系统时间 - 启动时设定的起点时间 = 上次持续计数经过总时间chronometer.stop();}@Overrideprotected void onResume() {super.onResume();chronometer.setBase(SystemClock.elapsedRealtime() - recordingTime );chronometer.start(); // 开始计数}
}

运行效果:
此时我们已经达到了前台计时,后台停止计时的计时器效果。

LifeCycles

上面我们虽然实现了计时器功能,但不是很好。我们将代码都放到了 MainActivity.java 中的生命周期中,如果对象少还好,如果对象多,大家都需要处理生命周期相关的行为,那么将会塞下很多代码,十分臃肿。并且这个代码的移植性几乎没有,为了优化这些问题,我们将使用 LifeCycles ,将这些功能放到 LifeCycles 中实现。

首先,创建一个 MyChronometer.java 文件,继承于 android.widget.Chronometer

创建完成后,默认报错,我们点击小灯泡,Create constructor matching super

由于我们要将这个对象放到 xml 界面做编辑,我们需要 attrs 属性参数,如下选择,

MyChronometer.java :我们还需要让他实现一个接口,实现生命周期的观察。

public class MyChronometer extends Chronometer implements LifecycleObserver {public MyChronometer(Context context, AttributeSet attrs) {super(context, attrs);}
}

以上为 MyChronometer.java 的初始代码,接下来我们要将之前实现的前台计数,后台暂停的计数器功能在这里实现:

实现逻辑与之前一样,在进入后台前,将已经记录的时间保存下来,下次进入前台时,跳过已经记录的时间,实现了继续计时。

@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) 是 LifecycleObserver 的特有写法,相当于在 MainActivity.java 中的 onPause() 代码块中写代码。由此可见,在实现了 LifecycleObserver 接口后,我们便可以在另一个类中自由的操纵生命周期了,增强了代码的移植性,并且减少了使得 MainActivity.java 中的代码更加简洁。

public class MyChronometer extends Chronometer implements LifecycleObserver {private long recordingTime;public MyChronometer(Context context, AttributeSet attrs) {super(context, attrs);}@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) // LifecycleObserver 特有写法private void pauseMeter(){recordingTime = SystemClock.elapsedRealtime() - getBase();stop(); // 不写也可以}@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)private void resumeMeter(){setBase(SystemClock.elapsedRealtime() - recordingTime);start();}}

在实现了计时器的生命周期后,我们需要去界面布局的 Text 中,将原本的 Chronometer 改为 MyChronometer。

然后来到 MainActivity.java,这里的代码将会变得十分简洁,关于生命周期的代码我们都不需要在这里实现了。我们在 MyChronometer 中实现了计时器的生命周期,在这里我们需要添加一句观察生命周期的代码:getLifecycle().addObserver(chronometer);

public class MainActivity extends AppCompatActivity {MyChronometer chronometer;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);chronometer = findViewById(R.id.meter);getLifecycle().addObserver(chronometer);}}

【安卓笔记】—— 感知生命周期 Lifecycles相关推荐

  1. day4 vue 学习笔记 组件 生命周期 数据共享 数组常用方法

    系列文章目录 day1学习vue2笔记 vue指令 day2 学习vue2 笔记 过滤器 侦听器 计算属性 axios day3 vue2 学习笔记 vue组件 day4 vue 学习笔记 组件 生命 ...

  2. activity 生命周期_如何理解安卓activity的生命周期(on-create篇)?

    个人认为用类比的方式来学习新事物比较容易接受.我这里用蝴蝶的一生来做比喻. OnCreate阶段就像是蝴蝶的幼虫刚出卵里孵化出来,蝴蝶的一生只可能出生一次,oncreate只能被创建一次.蝴蝶刚出生的 ...

  3. IOS学习笔记——ViewController生命周期详解

    在我之前的学习笔记中讨论过ViewController,过了这么久,对它也有了新的认识和体会,ViewController是我们在开发过程中碰到最多的朋友,今天就来好好认识一下它.ViewContro ...

  4. Android安卓——Android程序生命周期

    多处的开发者都给使用者了一个方便,给一些东西设置了一个生命周期的东西.本次学习主要对安卓中程序的生命周期进行讲解. 充分了解安卓生命周期,记住生命周期的优先级,为后续的开发打基础. Android程序 ...

  5. react学习笔记(8)生命周期回顾与再认识

    生命周期 生命周期是一个组件从创建到销毁的过程. 当组建实例被创建并且插入到DOM中,需要调用的函数,就是生命周期函数. 也就是说,组件加载完成前后.组件更新数据.组件销毁,所触发的一系列的方法. 1 ...

  6. Android笔记 activity生命周期 Tasks and back stack回退栈

    正常打开一个应用,先后调用Activity的onCreate.onStart.onResume 正常退出一个应用,先后调用Activity的onPause.onStop.onDestroy(进程被杀死 ...

  7. android学习笔记---36_Activity生命周期

    36_Activity生命周期 ----------------------------- 1.Activity生命周期,用于activity在运行时候受到一些突然事件的影响   ,例如:正在使用一个 ...

  8. rust笔记11 生命周期引用有效性

    函数参数等的生命周期 rust保证内存安全的手段之一是没有悬空的引用(指针),而这个靠编译期间强制生命周期检查实现.先给出生命周期的声明方式: &i32 // i32的引用 &'a i ...

  9. 让Flows感知生命周期

    点击上方蓝字关注我,知识会给你力量 这个系列我做了协程和Flow开发者的一系列文章的翻译,旨在了解当前协程.Flow.LiveData这样设计的原因,从设计者的角度,发现他们的问题,以及如何解决这些问 ...

最新文章

  1. 2345电脑管家_极限挑战:同时安装4大国产杀毒软件,我的电脑是最安全的?
  2. 自己动手——实现 Dustjs 中间件
  3. 深度学习框架Caffe2并入PyTorch,你的开发效率可能要提升不少
  4. 计算机联锁与全电子执行单元,计算机联锁全电子执行单元.doc
  5. Project Euler 92:Square digit chains 平方数字链
  6. Scala与Java差异(四)之数组操作
  7. oracle批量update
  8. leetcode276. 栅栏涂色
  9. Leetcode--78. 子集
  10. 20155220 2016-2017-2《Java程序设计》第五周学习总结
  11. POJ 1811 Prime Test
  12. 基本飞行模式中英文对照
  13. linux任务计划不执行时间,Linux任务计划、周期性任务执行
  14. 【POJ】1276 Cash Machine 【背包问题】
  15. python之路day9_Python之路,Day7 - 面向对象编程进阶
  16. 最好用的HDR图像处理器——Photomatix Pro新功能介绍及使用教程
  17. nn.PReLU()和nn.ReLU
  18. 移动通信网络协议 — GTP-U 隧道协议
  19. 游戏后端自增id选型
  20. chart metadata is missing these dependencies

热门文章

  1. 发展前景好的互联网技术方面,你觉得比较适合女孩子的都有哪些啊?
  2. In addition, Clem also revealed that they have
  3. rdt1.0,rdt2.0,rdt2.1,rdt2.2,rdt3.0
  4. 清空数据库事务日志_通过事务日志增长加快数据库恢复和长期运行的事务
  5. shell脚本视频学习1
  6. 剑指offer之 从尾到头打印链表
  7. 清除定时器 和 vue 中遇到的定时器setTimeout setInterval问题
  8. 关于ecshop模板更新版本的解决方法(三)
  9. 网络流(最大流):CodeForces 499E Array and Operations
  10. C#的百度地图开发(一)发起HTTP请求