CountDownTimer的使用以及解决Cancel无效的问题
来源:互联网 发布:php接口文档生成工具 编辑:程序博客网 时间:2024/05/17 03:33
在做项目的时候,需要一个倒计时的功能。查阅资料,Android提供了一个倒计时的功能 CountDownTimer。
官方提供的用法如下:
* Example of showing a 30 second countdown in a text field: * * <pre class="prettyprint"> * new CountDownTimer(30000, 1000) { * * public void onTick(long millisUntilFinished) { * mTextField.setText("seconds remaining: " + millisUntilFinished / 1000); * } * * public void onFinish() { * mTextField.setText("done!"); * } * }.start(); * </pre> *
创建CountDownTimer实例之后,必须通过start()函数将计时器开启,才能保证CountDownTimer运行。CountDownTimer还提供了cancel()方法,可以将计时器取消。
在使用CountDownTimer时,必须实现两个方法:onTick() 和 onFinish()。
在onTick(long millisUntilFinished) 中的参数millisUntilFinished是倒计时的剩余时间。在倒计时结束后会调用onFinish,倒计时结束后需要执行的操作可以写在onFinish中。
CountDownTimer(30000, 1000)中的30000,表示倒计时时间为30秒,1000表示每隔1秒钟调用一次onTick方法。
在使用过程中发现,在一个activity或者fragment中开启了计时器,如果倒计时没有完成即退出activity或者fragment,此时onTick仍然会继续执行,当执行到mTextField.setText()时,mTextField为null,导致程序crash。因此需要在onTick中进行非空判断。
如果是在Fragment中:
if(getActivity()!=null){ //todo }
如果是在Activity中:
if(!activity.isFinishing()){ //todo}
但是我们不希望在fragment或activity退出之后仍然调用onTick,即使已经做了非空判断。
我们希望在退出之后CountDownTimer也随之停止,因此在onTick中,当getActivity()==null或者activity.isFinishing()==true的时候,可以使用cancel方法取消掉计时器。
But!!!
经过实验发现,cancel在onTick中调用,是无法成功取消计时器的。
调用cancel之后,仍然会每隔固定时间调用onTick方法。
然而,在5.0及以上的系统中,cancel方法就可以起到作用。对比CountDownTimer的源码发现,在5.0中,增加了一个字段
/** * boolean representing if the timer was cancelled */ private boolean mCancelled = false;
通过mCancelled 标识当前计时器是否取消。
然后在handleMessage()中首先对mCancelled进行判断:
// handles counting down private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { synchronized (CountDownTimer.this) { if (mCancelled) { //**Attention!!!** return; } final long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime(); if (millisLeft <= 0) { onFinish(); } else if (millisLeft < mCountdownInterval) { // no tick, just delay until done sendMessageDelayed(obtainMessage(MSG), millisLeft); } else { long lastTickStart = SystemClock.elapsedRealtime(); onTick(millisLeft); // take into account user's onTick taking time to execute long delay = lastTickStart + mCountdownInterval - SystemClock.elapsedRealtime(); // special case: user's onTick took more than interval to // complete, skip to next interval while (delay < 0) delay += mCountdownInterval; sendMessageDelayed(obtainMessage(MSG), delay); } } } };
因此,如果想在onTick中调用cancel方法取消计时器,可以自定义一个CountDownTimerUtil,将5.0以上的CountDownTimer源码复制到CountDownTimerUtil即可。
5.0 CountDownTimer 源码:
http://download.csdn.net/detail/liuweiballack/8831309
4.4 CountDownTimer源码:
http://download.csdn.net/detail/liuweiballack/8831333
- CountDownTimer的使用以及解决Cancel无效的问题
- CountDownTimer的使用以及解决Cancel无效的问题
- CountDownTimer 解决 Cancel无效的问题
- 解决Android中CountDownTimer倒计时cancel方法无效的问题
- CountDownTimer空指针(NULL)与Cancel无效的问题
- 安卓CountDownTimer的cancel方法在onTick中调用无效的问题
- Timer的cancel问题
- android CountDownTimer的使用
- CountDownTimer的使用
- 计时器countdownTimer的使用
- CountDownTimer的使用
- CountDownTimer的使用
- android解决使用CountDownTimer出现的时间不稳定问题(执行多次变化加快)
- Android的 CountDownTimer的使用
- DBMS_SESSION.SET_CONTEXT的使用及无效权限问题的解决
- DBMS_SESSION.SET_CONTEXT的使用及无效权限问题的解决
- Android倒计时CountDownTimer的使用
- Android倒计时CountDownTimer的使用
- String、StringBuffer 和 StringBuilder的区别
- tcp的发送与接收缓冲区1
- Cocos2dx------华容道
- matlab中clc,close,close all,clear,clear all作用区别
- The Adventures of Tintin - Tintin in America
- CountDownTimer的使用以及解决Cancel无效的问题
- Android的AndroidManifest.xml文件介绍
- group by cube
- XMPP 群的设计和讨论
- 中国云计算论坛
- Maven之生成测试覆盖度的插件cobertura-maven-plugin的使用
- truct in6_addr has no member named in6_u
- hibernate opensession()和getCurrentSession()
- POJ - 2229