用Handler和Runnable替换CountDownTimer以获得更好的性能

时间:2018-03-25 10:55:22

标签: java android countdowntimer android-handler

我有基于CountDownTimer的游戏,它不断重复倒计时。如果用户响应number由某些onFinish()调用,或者如果时间已到,则此countDown计算用户对与clickListener相关的某些操作做出反应的时间。根据{{​​1}},调用方法succesCondition()success,如果游戏仍在运行,则会定义这些方法。

的OnCreate

fail

MainActivity

loop = gameLoop(time).start();

然而,此计时器在主线程上运行,并提供众所周知的问题public CountDownTimer gameLoop(int time){ return new CountDownTimer(time, time+100) { @Override public void onTick(long millisUntilFinished) { } @Override public void onFinish() { if (!Conditions.succesCondition(number)) { success(); } else { fail(); } } }; } public void success() { loop.cancel(); scoreCount++; animation.start(); } public void fail(){ loop.cancel(); } ,我发现这是skipped xx frames, your app might be doing too much work on its main thread的常见问题,将其替换为CountDownTimer是一种解决方案。

我无法将此计时器放在Handler中,因为它主要执行与UI相关的任务(TextViews,TextSwitcher,某些progressBar等AsyncTask方法。我没有把它放在那些代码中更清晰地查看主要问题的方法。我正在尝试重构success() - 像处理程序的概念和runnable来替换我的Timer,但我实际上什么都没有。你可以看到我正在使用只有CountDownTimer方法,onFinish不是必需的。

3 个答案:

答案 0 :(得分:1)

您可以使用AsyncTask处理此情况并覆盖onProgressUpdate方法。

这里有an example关于如何实现与AsyncTask主线程交互的行为。该示例显示了下载的更新,可以轻松转换为您的特定计时器问题。

<强>更新

  

在我的情况下,几乎所有代码都在onProgressUpdate中,是吗?   还有什么意义吗?

不,您的代码不在onProgressUpdateonProgressUpdate方法只会在您的用户界面中更新您的计时器。据我所知,成功和失败也将基于用户行为触发。然后触发这些操作,您也可以停止AsyncTask更新您的计时器。您只需要AsyncTask不时更新计时器值。

Activity完成后,您的AsyncTask会收到回电信息。请参阅上例中的mNotificationHelper.completed();函数。当计时器结束时,在Activity中通知您,然后您可以在那里执行以下任务。

public void completed()    {
    if (!Conditions.succesCondition(number)) {
        success();
    } else {
        fail();
    }
}

答案 1 :(得分:1)

我建议使用Public Sub New() InitializeComponent() if Not MyBase.ParentForm.FormBorderStyle = FormBorderStyle.None Then MsgBox("Test Message") End If End Sub java.util.Timerjava.util.TimerTask的组合。首先创建一个Activity.runOnUiThread()并调用其中一个Timer方法。需要在main(ui)线程上执行的任何操作都可以包含在schedule...()中。如果不再需要这些对象,请务必在runOnUiThread(() -> { ...})cancel()上致电TimerTask。取消Timer也会取消Timer

以下是这样的结果:

TimerTask

答案 2 :(得分:0)

行。我终于想出了如何用处理程序处理它(呵呵):

public void startGameAction() {

    //My game actions

    handler = new Handler();
    runnable = () -> {
        if (!Conditions.succesCondition(number)) {
            success();
        } else {
            fail();
        }
    };
    handler.postDelayed(runnable,time);
}

public void success(){
        handler.removeCallbacks(runnable);
        handler = null;

        scoreCount++;
        //other stuff
        startGameAction();
    }

 private void fail() {
    handler.removeCallbacks(runnable);
    //other stuff
}

onCreate仅将startGame调用,handler和runnable定义为类字段

startGameAction();