CountDownTimer用法详解

本文探讨了在Android中如何正确地使用CountDownTimer类与Activity的生命周期相结合,确保即使在Activity重建时也能准确地记录倒计时状态,避免重复启动。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

[html]  view plain copy
  1. <TextView  
  2.             android:id="@+id/timer"  
  3.             android:layout_width="fill_parent"  
  4.             android:layout_height="wrap_content"  
  5.             android:textColor="#00ff00"  
  6.             android:textSize="20sp"  
  7.             android:background="#000000" />  
[html]  view plain copy
  1. ActivityA onCreate(){  
  2. ...  
  3. mTv = (TextView) findViewById(R.id.timer);  
  4. myTimer = new CountDownTimer(myTime, 100) {  
  5.   
  6.     @Override  
  7.     public void onTick(long millisUntilFinished) {  
  8.         mTv.setText("剩余时间: " + millisUntilFinished / 1000 + "."  
  9.             + (millisUntilFinished % 1000) / 100+"秒");  
  10.         }  
  11.   
  12.     @Override  
  13.     public void onFinish() {  
  14.         if (myTime / 1000 == 0) {  
  15.             mTv.setText("时间到!");  
  16.             Intent i = new Intent(ActivityA.this,ActivityB.class);  
  17.             String answer = getSelectedAnswer();  
  18.             i.putExtra(Constants.EXTRA_MESSAGE, answer);  
  19.             startActivity(i);  
  20.             finish();  
  21.   
  22.         }  
  23.     }  
  24. }.start();  
  25. ...  
  26. }  

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

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

[html]  view plain copy
  1. @Override  
  2.     public Object onRetainNonConfigurationInstance() {  
  3.         return myTimer;  
  4.     }  

保存已经历时间:

[html]  view plain copy
  1. public void onSaveInstanceState(Bundle savedInstanceState) {  
  2.         savedInstanceState.putLong(TIMER_STATE, myTime);  
  3.         super.onSaveInstanceState(savedInstanceState);  
  4.     }  
取到这些保存的状态,使用一下代码

[html]  view plain copy
  1. onCreate(){  
  2. ...  
  3. if (savedInstanceState != null) {  
  4.         // Restore value of members from saved state  
  5.         myTime = savedInstanceState.getLong(TIMER_STATE);  
  6.         myTimer = (CountDownTimer) getLastNonConfigurationInstance();  
  7.         myTimer.cancel();  
  8.               
  9. }  
  10.   
  11. }  

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值