android的CountDownTimer开始时间不准或者不能倒计时到0的一种解决思路

您所在的位置:网站首页 倒计时作用 android的CountDownTimer开始时间不准或者不能倒计时到0的一种解决思路

android的CountDownTimer开始时间不准或者不能倒计时到0的一种解决思路

#android的CountDownTimer开始时间不准或者不能倒计时到0的一种解决思路| 来源: 网络整理| 查看: 265

很多情况下,android需要使用倒计时的功能,网上有许多的实现方式,在这里我来跟大家讨论下android的CountDownTimer这个类的实际使用。

CountDownTimer这个类的使用非常的简单。

new CountDownTimer(countTime , internal){ @Override public void onTick(long l) { // 每隔internal毫秒就会回调一次该方法 } @Override public void onFinish() { // 当countTime倒计时到了之后,会回调该方法 } }.start(); // 最后记得start

传两个参数就可以了。下面看下我在实际使用中的坑,有图有真相

不知道有没有看出异常,就是下面的两个BUG!!!!!!!!

为了以证清白我,我把我的代码都帖出来

public class CountTimerActivity extends AppCompatActivity implements View.OnClickListener{ private int mCount = 20 ; private TextView countTv ; private Button start , stop ; CountDownTimer countDownTimer ; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_count_timer); start = (Button) findViewById(R.id.start); stop = (Button)findViewById(R.id.stop); countTv = (TextView) findViewById(R.id.time); getSupportActionBar().setTitle("倒计时测试"); countDownTimer = new CountDownTimer(mCount*1000 , 1000) { @Override public void onTick(long l) { Log.d("CJT", "onTick----l=="+l); countTv.setText((int)l/1000+" 秒"); } @Override public void onFinish() { Log.d("CJT", "onFinish-------"); countTv.setText("finish!"); } }; start.setOnClickListener(this); stop.setOnClickListener(this); } @Override public void onClick(View view) { switch (view.getId()){ case R.id.start: countDownTimer.start(); break; case R.id.stop: countDownTimer.cancel(); break; } } @Override protected void onDestroy() { if(countDownTimer != null ) countDownTimer.cancel(); super.onDestroy(); } }

按照常规的使用方法却出现了意想不到的BUG,当然程序是死的,人是活的,总有办法看可以解决的。

一、下面看下怎么解决第一个BUG:时间直接从20秒倒计时跳到了18秒?

出现这个问题的主要原因是我们在onTick(long l)中取到的l有误差,理论上应该从20000减去1000变为19000 ,可是打印结果却是18999,这1毫秒的误差导致在强制类型转换少了1秒,而且随着onTick方法不断回调,这个误差也越来越大,在20秒的时间中相差了2000-1982=8毫秒(最后一次打印,理论值2000,实际值1982)。

明白了这个问题出现的原因就好解决了,直接将原来的countTime补上这个误差就可以了。

看下运行的Log

07-12 18:33:32.417 4724-4724/com.cjt.testvolley D/CJT: onTick----l==20050 07-12 18:33:33.417 4724-4724/com.cjt.testvolley D/CJT: onTick----l==19049 07-12 18:33:34.417 4724-4724/com.cjt.testvolley D/CJT: onTick----l==18048 07-12 18:33:35.417 4724-4724/com.cjt.testvolley D/CJT: onTick----l==17046 07-12 18:33:36.417 4724-4724/com.cjt.testvolley D/CJT: onTick----l==16045 07-12 18:33:37.417 4724-4724/com.cjt.testvolley D/CJT: onTick----l==15044 07-12 18:33:38.427 4724-4724/com.cjt.testvolley D/CJT: onTick----l==14042 07-12 18:33:39.427 4724-4724/com.cjt.testvolley D/CJT: onTick----l==13041 07-12 18:33:40.427 4724-4724/com.cjt.testvolley D/CJT: onTick----l==12040 07-12 18:33:41.427 4724-4724/com.cjt.testvolley D/CJT: onTick----l==11038 07-12 18:33:42.427 4724-4724/com.cjt.testvolley D/CJT: onTick----l==10036 07-12 18:33:43.427 4724-4724/com.cjt.testvolley D/CJT: onTick----l==9035 07-12 18:33:44.437 4724-4724/com.cjt.testvolley D/CJT: onTick----l==8034 07-12 18:33:45.427 4724-4724/com.cjt.testvolley D/CJT: onTick----l==7033 07-12 18:33:46.427 4724-4724/com.cjt.testvolley D/CJT: onTick----l==6033 07-12 18:33:47.427 4724-4724/com.cjt.testvolley D/CJT: onTick----l==5032 07-12 18:33:48.436 4724-4724/com.cjt.testvolley D/CJT: onTick----l==4031 07-12 18:33:49.436 4724-4724/com.cjt.testvolley D/CJT: onTick----l==3030 07-12 18:33:50.436 4724-4724/com.cjt.testvolley D/CJT: onTick----l==2029 07-12 18:33:51.436 4724-4724/com.cjt.testvolley D/CJT: onTick----l==1027 07-12 18:33:52.466 4724-4724/com.cjt.testvolley D/CJT: onFinish-------

运行还算正常,而且强转之后绝对不会出错了!

二、下面看下怎么解决第二个BUG:时间怎么不到0?

出现这个问题的主要原因是我认为是在onTick(long l)中取到的l减去internal(我们设定的间隔时间)还比internal小的时候,会回调onFinsh()方法,而不再回调onTick()方法了,有小伙伴在想是否可以在onFinis()方法中直接设置文本框为0秒呢?我试过,但是不起作用的,对这个有兴趣的可以去研究下。还是回到这个问题,我们是为了解决为何不显示0,还有其他的方法可以搞定的嘛!我呢,还是在总时间上动手脚,不过这次是直接加1000毫秒,在显示的时候减去这一秒,具体操作如下。

这样改动之后下面看下最后的效果:

好了,基本上实现了想要的效果,也用另一种方式解决了两个BUG,注意这里的误差时间不一定是50毫秒,要根据实际情况来定,有可能要设定的更大才行。

最后修改后的代码,主要部分

countDownTimer = new CountDownTimer(mCount*1000 + 1050 , 1000) { @Override public void onTick(long l) { Log.d("CJT", "onTick----l=="+l); countTv.setText(((int)l/1000 -1)+" 秒"); } @Override public void onFinish() { Log.d("CJT", "onFinish-------"); countTv.setText("finish!"); } };



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3