android - 实现定时刷新页面:使用CountDownTimer
访问量: 2986
参考: https://stackoverflow.com/questions/21726055/android-loop-part-of-the-code-every-5-seconds 和 https://stackoverflow.com/questions/8278041/how-to-create-an-infinite-loop
完整的例子如下: (一反短平快的博客风格,还是记录下来吧,这里有点儿坑。例子之后是几个讲解的注意点)
补充:实在是太坑了....
public class YourActivity ... { private CountDownTimer countDownTimer; private long AUTO_REFRESH_INTERVAL = 10000; // 10秒执行一次。常量。 // 初始化方法 public void onCreate(){ startCountDownTimer(); } // 初始化并且启动count down timer. private void startCountDownTimer(){ // 注意这里要做个非空判断。 if(countDownTimer == null){ countDownTimer = new CountDownTimer(600 * AUTO_REFRESH_INTERVAL, AUTO_REFRESH_INTERVAL) { @Override public void onTick(long millisUntilFinished) { Log.d(TAG, "== in CountDownTimer, onTick, refreshData... "); refreshData(false); } @Override public void onFinish() { Log.d(TAG, "== in CountDownTimer, countDownTimer, onFinish"); // start again. start(); } }; } restartCountDownTimer(); } // 重新启动. private void restartCountDownTimer(){ countDownTimer.cancel(); //首次计数器会被立刻触发。所以 延后特定的时间来执行。 // (注意:不要这样做,会导致有 timer.start()的两个方法再跑。(同一个对象,运行两个方法,应该是多线程。。。无语了) // 应该直接 countDownTimer.start()就好。 /* new Handler().postDelayed(new Runnable() { @Override public void run() { countDownTimer.start(); } }, AUTO_REFRESH_INTERVAL); */ countDownTimer.start(); } // 记得这里要修改。如果你的是Fragment的话,在第一次显示的时候,这个方法就会被触发。 public void onResume(){ countDownTimer.cancel(); countDownTimer.start() } private void refreshData(final boolean isManuallyExecuted) { // ... // 手动刷新后,下次10秒后才会自动刷新 if(isManuallyExecuted){ restartCountDownTimer(); } }
添加如下代码:
private CountDownTimer countDownTimer; // 第一个参数是定时器执行的总时间,第二个参数是每隔多久,就触发一次 onTick countDownTimer = new CountDownTimer(600000, 10000) { @Override public void onTick(long millisUntilFinished) { Log.d(TAG, "== in CountDownTimer, onTick"); refreshData( false ); // 注意这里的参数,false 表示:“不是手动触发” } // 定时器结束后,自动重启。 @Override public void onFinish() { Log.d(TAG, "== in CountDownTimer, countDownTimer, onFinish"); // start again. start(); } }.start();
注意1: 很多时候,手动刷新之后,需要重置 定时器:
// 手动刷新后,下次10秒后才会自动刷新 if(isManuallyExecuted){ countDownTimer.cancel(); new Handler().postDelayed(new Runnable() { @Override public void run() { countDownTimer.start(); } }, 10000); }
所有有上述代码。
注意2: 在首次启动时, 要延后一段时间执行,并且要区分被执行的方法“是不是手动触发”。如果不区分的话, 就会陷入到 “counter调用自动方法,立刻执行,该方法执行完毕后,重启counter, 该counter调用自动方法,立刻执行。。。" 是个死循环
注意3:根据实际观察,如果定义了第二个参数是10000, 我们发现被触发的时间,会延后10毫秒。
日志:
09-02 07:23:51.403 8090-8090/com.yunbi D/MarketFragmentN: == in CountDownTimer, onTick 09-02 07:24:01.403 8090-8090/com.yunbi D/MarketFragmentN: == in CountDownTimer, onTick 09-02 07:24:11.413 8090-8090/com.yunbi D/MarketFragmentN: == in CountDownTimer, onTick 09-02 07:24:21.433 8090-8090/com.yunbi D/MarketFragmentN: == in CountDownTimer, onTick 09-02 07:24:31.443 8090-8090/com.yunbi D/MarketFragmentN: == in CountDownTimer, onTick 09-02 07:24:41.433 8090-8090/com.yunbi D/MarketFragmentN: == in CountDownTimer, onTick 09-02 07:24:51.453 8090-8090/com.yunbi D/MarketFragmentN: == in CountDownTimer, onTick 09-02 07:25:01.463 8090-8090/com.yunbi D/MarketFragmentN: == in CountDownTimer, onTick 09-02 07:25:11.473 8090-8090/com.yunbi D/MarketFragmentN: == in CountDownTimer, onTick 09-02 07:25:21.473 8090-8090/com.yunbi D/MarketFragmentN: == in CountDownTimer, onTick 09-02 07:25:31.483 8090-8090/com.yunbi D/MarketFragmentN: == in CountDownTimer, onTick 09-02 07:25:41.513 8090-8090/com.yunbi D/MarketFragmentN: == in CountDownTimer, onTick 09-02 07:25:51.533 8090-8090/com.yunbi D/MarketFragmentN: == in CountDownTimer, onTick 09-02 07:26:01.543 8090-8090/com.yunbi D/MarketFragmentN: == in CountDownTimer, onTick 09-02 07:26:11.553 8090-8090/com.yunbi D/MarketFragmentN: == in CountDownTimer, onTick 09-02 07:26:21.553 8090-8090/com.yunbi D/MarketFragmentN: == in CountDownTimer, onTick
所以,如果你的一个定时任务,每隔10秒执行一次的话,如果把总时间设置成20秒,就会发现该任务只会触发一次。 原因是20秒内不会出现两次。估计需要20.1秒,才能成功触发两次。
为了弥补这个缺陷,建议把总时间设置的长一些