Android:使用CountDownTimer与Thread.sleep()的优缺点是什么?

时间:2017-03-06 13:17:18

标签: android multithreading countdowntimer

我想做什么:

我想使用工作线程定期更新UI线程中的文本字段。比方说,每2秒持续30秒。即使应用程序不在前台,我也需要进行30秒倒计时。目前,我正在评估两种不同方法(都使用工作线程)实现这一点的优点。我不会在这里发布完整的代码来简化事情,也因为我没有要求在我的代码中发现任何问题。两种解决方案都运行良好。

解决方案#1 - 在Thread.sleep()循环中使用for

for (int i = 30; i > 0; i-=2) {
    Message msg = mHandler.obtainMessage(MSG_ID, i, 0);
    msg.sendToTarget();

    try {
        Thread.sleep(2000);
    } catch(Throwable t) {
        // catch error
    }

}

解决方案#2 - 使用CountDownTimer

Looper.prepare()

new CountDownTimer(30000, 2000) {
    public void onTick(long millUntilFinish) {
        int seconds = (int)(millUntilFinish);
        Message msg = mHandler.obtainMessage(MSG_ID, seconds, 0);
        msg.sendToTarget();
    }

    public void onFinish() {
        // left blank for now
    }
}.start();

Looper.loop();

我的问题

虽然两者都有效,但我想知道是否有“更好”或“首选”的方式来做任何理由。我认为可能存在电池寿命方面,特别是性能,准确度或代码设计方面,其中一种解决方案优于另一种解决方案。

到目前为止,我所做的是回答这个问题

我自己对阅读this SO questionCountDownTimer的{​​{3}}的评价是因为两者都在工作线程上执行,所以两者都没有ANR可能性。这两个解决方案还将保证只有在上一次更新完成后才会发生一次“更新”。不幸的是,这就是我所拥有的,并希望有人可以帮助或指导我提出一个我可能忽略或找不到的有见地和/或类似的问题。

我有点谨慎地写这个问题,因为我没有需要调试的有问题的代码,但我认为这属于“{3}}类别的”特定编程问题“,这个问题尚未得到解答,并且不包括在主题外答案列表中。

2 个答案:

答案 0 :(得分:1)

1.Calling Thread.sleep暂停线程执行一段时间,其中倒数计时器实际上使用回调来通知计时器到期事件,并且本质上是异步的。

2.如果线程执行暂停,则在睡眠超时之前,您将无法使用该特定线程进行任何其他操作,因此不建议使用Thread.sleep方法。显然,如果必须恢复线程执行并暂停它,则在cpu上有一个加载。在倒数计时器的情况下,线程继续处于执行/空闲状态,并且当事件发生时,它将触发相应的侦听器。 / p>

答案 1 :(得分:0)

call Thread.sleep() method is not good idea beacuse ii sleep the UI Thread and disadvantage of  CountDownTimer is, It Will stop when ur screen is off hence instead of this two try  Handler for that like this


 Handler handler;
    Runnable runnable;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        handler = new Handler();
        Runnable runnable = new Runnable() {
            @Override
            public void run()
            {
                if (dataReceived)
                {
                    cancelHandler();
                }
            }
        };
        handler.postDelayed(runnable, 100);
    }

    public void cancelHandler()
    {
        handler.removeCallbacks(runnable);
    }