【安卓笔记】—— 感知生命周期 Lifecycles
感知生命周期 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相关推荐
- day4 vue 学习笔记 组件 生命周期 数据共享 数组常用方法
系列文章目录 day1学习vue2笔记 vue指令 day2 学习vue2 笔记 过滤器 侦听器 计算属性 axios day3 vue2 学习笔记 vue组件 day4 vue 学习笔记 组件 生命 ...
- activity 生命周期_如何理解安卓activity的生命周期(on-create篇)?
个人认为用类比的方式来学习新事物比较容易接受.我这里用蝴蝶的一生来做比喻. OnCreate阶段就像是蝴蝶的幼虫刚出卵里孵化出来,蝴蝶的一生只可能出生一次,oncreate只能被创建一次.蝴蝶刚出生的 ...
- IOS学习笔记——ViewController生命周期详解
在我之前的学习笔记中讨论过ViewController,过了这么久,对它也有了新的认识和体会,ViewController是我们在开发过程中碰到最多的朋友,今天就来好好认识一下它.ViewContro ...
- Android安卓——Android程序生命周期
多处的开发者都给使用者了一个方便,给一些东西设置了一个生命周期的东西.本次学习主要对安卓中程序的生命周期进行讲解. 充分了解安卓生命周期,记住生命周期的优先级,为后续的开发打基础. Android程序 ...
- react学习笔记(8)生命周期回顾与再认识
生命周期 生命周期是一个组件从创建到销毁的过程. 当组建实例被创建并且插入到DOM中,需要调用的函数,就是生命周期函数. 也就是说,组件加载完成前后.组件更新数据.组件销毁,所触发的一系列的方法. 1 ...
- Android笔记 activity生命周期 Tasks and back stack回退栈
正常打开一个应用,先后调用Activity的onCreate.onStart.onResume 正常退出一个应用,先后调用Activity的onPause.onStop.onDestroy(进程被杀死 ...
- android学习笔记---36_Activity生命周期
36_Activity生命周期 ----------------------------- 1.Activity生命周期,用于activity在运行时候受到一些突然事件的影响 ,例如:正在使用一个 ...
- rust笔记11 生命周期引用有效性
函数参数等的生命周期 rust保证内存安全的手段之一是没有悬空的引用(指针),而这个靠编译期间强制生命周期检查实现.先给出生命周期的声明方式: &i32 // i32的引用 &'a i ...
- 让Flows感知生命周期
点击上方蓝字关注我,知识会给你力量 这个系列我做了协程和Flow开发者的一系列文章的翻译,旨在了解当前协程.Flow.LiveData这样设计的原因,从设计者的角度,发现他们的问题,以及如何解决这些问 ...
最新文章
- 2345电脑管家_极限挑战:同时安装4大国产杀毒软件,我的电脑是最安全的?
- 自己动手——实现 Dustjs 中间件
- 深度学习框架Caffe2并入PyTorch,你的开发效率可能要提升不少
- 计算机联锁与全电子执行单元,计算机联锁全电子执行单元.doc
- Project Euler 92:Square digit chains 平方数字链
- Scala与Java差异(四)之数组操作
- oracle批量update
- leetcode276. 栅栏涂色
- Leetcode--78. 子集
- 20155220 2016-2017-2《Java程序设计》第五周学习总结
- POJ 1811 Prime Test
- 基本飞行模式中英文对照
- linux任务计划不执行时间,Linux任务计划、周期性任务执行
- 【POJ】1276 Cash Machine 【背包问题】
- python之路day9_Python之路,Day7 - 面向对象编程进阶
- 最好用的HDR图像处理器——Photomatix Pro新功能介绍及使用教程
- nn.PReLU()和nn.ReLU
- 移动通信网络协议 — GTP-U 隧道协议
- 游戏后端自增id选型
- chart metadata is missing these dependencies
热门文章
- 发展前景好的互联网技术方面,你觉得比较适合女孩子的都有哪些啊?
- In addition, Clem also revealed that they have
- rdt1.0,rdt2.0,rdt2.1,rdt2.2,rdt3.0
- 清空数据库事务日志_通过事务日志增长加快数据库恢复和长期运行的事务
- shell脚本视频学习1
- 剑指offer之 从尾到头打印链表
- 清除定时器 和 vue 中遇到的定时器setTimeout setInterval问题
- 关于ecshop模板更新版本的解决方法(三)
- 网络流(最大流):CodeForces 499E Array and Operations
- C#的百度地图开发(一)发起HTTP请求