当需要倒计时器功能,sdk自带的CountDownTimer类往往是首选工具。网上有很多针对该类的介绍,但鲜有文章涉及到CountDownTimer如何与Activity生命周期相互作用。

之前有个项目需要倒计时器功能,要求在ActivityA创建时开始倒计时,倒计时结束时通过intent创建另一个ActivityB。于是有下面代码

<TextViewandroid:id="@+id/timer"android:layout_width="fill_parent"android:layout_height="wrap_content"android:textColor="#00ff00"android:textSize="20sp"android:background="#000000" />
ActivityA onCreate(){
...
mTv = (TextView) findViewById(R.id.timer);
myTimer = new CountDownTimer(myTime, 100) {@Overridepublic void onTick(long millisUntilFinished) {mTv.setText("剩余时间: " + millisUntilFinished / 1000 + "."+ (millisUntilFinished % 1000) / 100+"秒");}@Overridepublic void onFinish() {if (myTime / 1000 == 0) {mTv.setText("时间到!");Intent i = new Intent(ActivityA.this,ActivityB.class);String answer = getSelectedAnswer();i.putExtra(Constants.EXTRA_MESSAGE, answer);startActivity(i);finish();}}
}.start();
...
}

上面的代码确实能实现需要的功能,但是没有考虑在倒计时结束之前ActivityA可能被重建。当旋转屏幕或系统设置更新时,都会造成当前Activity的重建。结果是,每当ActivityA重建时,开始一个新的myTimer,而之前的myTimer并未被销毁。于是多个ActivityB会被创建,这明显是我们不希望发生的。

我们需要在ActivityA销毁前保存该myTimer至整个application的生命周期,然后在重建时先cancel掉之前保存的myTimer,再创建一个新的myTimer。而这个新的myTimer的第一个参数(剩余时间)应该减去ActivityA重建之前已经经历的时间。保存myTimer,可以使用

@Overridepublic Object onRetainNonConfigurationInstance() {return myTimer;}

保存已经历时间:

public void onSaveInstanceState(Bundle savedInstanceState) {savedInstanceState.putLong(TIMER_STATE, myTime);super.onSaveInstanceState(savedInstanceState);}

取到这些保存的状态,使用一下代码

onCreate(){
...
if (savedInstanceState != null) {// Restore value of members from saved statemyTime = savedInstanceState.getLong(TIMER_STATE);myTimer = (CountDownTimer) getLastNonConfigurationInstance();myTimer.cancel();}}

这样保证了任何时间只有一个myTimer在计时,并且Activity的重建并不会暂定计时。

CountDownTimer用法详解相关推荐

  1. python argv 详解_Python3 sys.argv[ ]用法详解

    sys.argv[]说白了就是一个从程序外部获取参数的桥梁,这个"外部"很关键,因为我们从外部取得的参数可以是多个,所以获得的是一个列表(list),也就是说sys.argv其实可 ...

  2. oracle中的exists 和 not exists 用法详解

    from:http://blog.sina.com.cn/s/blog_601d1ce30100cyrb.html oracle中的exists 和 not exists 用法详解 (2009-05- ...

  3. ROW_NUMBER() OVER()函数用法详解 (分组排序 例子多)

    ROW_NUMBER() OVER()函数用法详解 (分组排序 例子多) https://blog.csdn.net/qq_25221835/article/details/82762416 post ...

  4. python的继承用法_【后端开发】python中继承有什么用法?python继承的用法详解

    本篇文章给大家带来的内容是关于python中继承有什么用法?python继承的用法详解,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 面向对象三大特征 1.封装:根据职责将属性和方法 ...

  5. C++中substr()函数用法详解

    C++中substr()函数用法详解 原型: string substr (size_t pos = 0, size_t len = npos) const; 返回一个新构造的string对象,其值初 ...

  6. php theme_path,PHP_Yii2主题(Theme)用法详解,本文实例讲述了Yii2主题(Theme) - phpStudy

    Yii2主题(Theme)用法详解 本文实例讲述了Yii2主题(Theme)用法.分享给大家供大家参考,具体如下: 首先看看主要的配置方式: 'components' => [ 'view' = ...

  7. LayoutInflater的inflate函数用法详解

    LayoutInflater的inflate函数用法详解 LayoutInflater作用是将layout的xml布局文件实例化为View类对象. 获取LayoutInflater的方法有如下三种: ...

  8. Ext.Net学习笔记22:Ext.Net Tree 用法详解

    上面的图片是一个简单的树,使用Ext.Net来创建这样的树结构非常简单,代码如下: <ext:TreePanel runat="server"><Root> ...

  9. WinDbg用法详解

    WinDbg用法详解 对WinDbg的方方面面作了详细的讲解. 转载于:https://blog.51cto.com/laokaddk/125111

最新文章

  1. novaclient的api调用流程与开发
  2. tf.keras.layers.MaxPool2D 最大池化层 示例
  3. C++知识点59——类模板(4、类模板的模板参数是一个类模板)
  4. ecs服务器配置git_阿里云 ECS服务器(CentOS 7)安装和使用Gitlab教程
  5. 期待的程序员的生活并非你想象的那么简单!
  6. 12 DOM操作的相关案例
  7. LINUX SAN 500G重新分区、格式化,后成功恢复数据90%
  8. 亚马逊表示并未放弃WP平台:正在打造新应用
  9. 软考-嵌入式系统设计师-笔记:嵌入式系统软件基础知识
  10. 女生学计算机专业好吗_百度文库,没考上高中的女生学什么最好
  11. 《故障排除》——VMware Horizon agent:failed to install vmwusm driveer| winerror code 3758096967
  12. 阅读界面怎么用html做,如何在A4纸页面中制作HTML页面?
  13. C#中Atan()与Atan2()
  14. 联网查看图片的Demo
  15. 1万的android手机推荐,Vertu推天价Android手机:入门级售价1万美元
  16. numpy高维矩阵reshape
  17. ERP不规范,同事哭晕在厕所
  18. Excel基础篇(三):vlookup根据A列查询B列
  19. Windows server2008部署SpringBoot的jar项目
  20. 台湾晟邦电机变频调速需要注意什么?

热门文章

  1. 北航计算机系导师,北航计算机学院计算机系统结构导师介绍:钱德沛
  2. 太牛了!知识图谱原理与实战
  3. HashMap底层红黑树原理(超详细图解)+手写红黑树代码
  4. JavaEE就业学习路线(给初学者以及自学者一个学习方向)
  5. PHP中执行sql语句
  6. boost::mpl操作类型向量
  7. CI持续集成、持续交付、持续部署
  8. 刚毕业女大学生竟和“禽兽”做出这种事
  9. 夜天之书 #14 Respond second
  10. 粒子群算法优化PID参数实例