CountDownTimer 解决 Cancel无效的问题
来源:互联网 发布:淘宝网夏秋棉麻连衣裙 编辑:程序博客网 时间:2024/06/06 13:57
转自:http://blog.csdn.net/liuweiballack/article/details/46605787
在做项目的时候,需要一个倒计时的功能。查阅资料,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中
但是我们不希望在fragment或activity退出之后仍然调用onTick,即使已经做了非空判断。
我们希望在退出之后
if(!activity.isFinishing()){ //todo}
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问题
- 解决ListView的 setEmptyView无效的问题
- 解决UIImageView的tintColor无效的问题
- android解决使用CountDownTimer出现的时间不稳定问题(执行多次变化加快)
- 解决绑定句柄无效的问题
- ListView.setOnItemClickListener无效问题的解决
- 解决win7下文件拖拽无效的问题
- ListView.setOnItemClickListener无效问题的解决
- codeblocks中断点无效问题的解决
- 解决LinkBar.selectedInex设置无效的问题
- 解决win7下文件拖拽无效的问题
- 解决CMFCColorButton的Other按钮无效问题
- 希尔排序
- 第十。十一周项目3 - 警察和厨师——1
- java中获取当前日期和前一天日期
- 转:java中时间戳各种实现方式获取效率
- 归并排序
- CountDownTimer 解决 Cancel无效的问题
- 【Spring4揭秘 BeanFactory】修改Bean---BeanPostProcessor
- LeetCode-168.Excel Sheet Column Title
- 怎样在Eclipse中快速查看各种源代码?
- 鼠标双击
- 基数排序
- 月薪3万的程序员告诉你:这样工作才能拿高薪
- Android有效地减少方法数
- 四大组件之Service(二)-Service在各种情况下的生命周期