在不销毁和重新创建的情况下暂停计时器 - Android

Pausing timer without destroy and re-create - Android

我有这个 AsyncTask,每次执行 "doInBackground" 时它会休眠 0.1 秒,在此之前我使用 CountDownTimer 来控制我的时间。

我的问题是:我想实现一个可以暂停而不调用 .cancel() 和何时开始创建另一个计时器的计时器。

有没有办法实现这个android?我没有找到如何以不同的方式做到这一点。你能举个例子吗?

我在哪里找到取消计时器的示例:

编辑

回答Kevin Krumwiede:这个项目是一种游戏,我必须在规定的时间内击中方块,所以我想实现一种方法来在玩家使用某种特殊力量(击中一个指定的按钮)。

EDIT2

回答Kushal:我不知道你有没有编译这段代码,但是我不能使用task1变量。代码如下:

   public void doIt(){
        final ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();

        final Runnable task =
        new Runnable() {

            @Override
            public void run() {
                timerAsyncTask.execute();

                if(true) {
                    exec.shutdown();    // shutdown this execution
                    //exec = Executors.newSingleThreadScheduledExecutor();
                    exec.scheduleAtFixedRate(task, 0, 100, TimeUnit.MILLISECONDS);
                }
            }
        };
        exec.scheduleAtFixedRate(task, 0, 100, TimeUnit.MILLISECONDS);
    }

这里 exec = Executors.newSingleThreadScheduledExecutor(); 它显示了一个错误:

Error:(33, 21) error: cannot assign a value to final variable exec

我觉得挺好的,一旦exec是final变量。

这里 exec.scheduleAtFixedRate(task, 0, 100, TimeUnit.MILLISECONDS); 我又遇到了一个错误:

Error:(34, 46) error: variable task might not have been initialized

你能解释一下,我该如何使用这段代码?我对 android 很陌生。 谢谢。

您可以使用 ScheduledExecutorService class

来实现您的要求

ScheduledExecutorServiceTimer class 之间的基本区别是:

  • 使用定时器class,您无法检查您的执行情况。您可以开始和停止执行但不能根据条件检查执行
  • ScheduledExecutorService 提供了检查启动和停止调用之间的执行情况的方法 运行。如果任务的任何执行遇到异常,则后续执行将被抑制

我们如何实现您的要求:

  • 我们在 doInBackground() 执行之间需要 0.1 秒的延迟
  • 我们应该能够在其他执行开始时暂停我们的执行

    ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
    
    Runnable task1 = new Runnable() {
      public void run() {
        // start your AsyncTask here
        new <your_task>().execute();
    
        if (<check_your_condition_when_to_pause>) {
          exec.shutdown();    // shutdown this execution 
          exec = Executors.newSingleThreadScheduledExecutor();
          exec.scheduleAtFixedRate(task1, 0, 100, TimeUnit.MILLISECONDS);
          // here i have passed task1 for example
          // here we need to pass next task runnable which
          // we want to run after 0.1 seconds
        } else {
          // continue normal
        }
    
      }
    };
    
    exec.scheduleAtFixedRate(task1, 0, 100, TimeUnit.MILLISECONDS);
    

信用参考:Answer 1 and Answer 2

希望本文能帮助您解决一些疑惑

我建议您完全避免 Android 中的定时器。 Android 有一个重量轻且更好的解决方案,称为 Handler

您可以找到这两者之间的比较 here。总结

比较处理程序 VS 定时器

  • 虽然重新调度 Handler 很容易,但您不能重新调度 Timer
  • 在 Handler 中,您可以附加到任何 Runnable 但 Timer 计划 一个 TimerTask
  • TimerTask 是纯粹的后台任务,所以你不能更新 UserInterface,但 Handler 的 Runnables 并非如此
  • 计时器导致异常
  • 与 Handler 相比,Timer 往往会泄漏更多内存,请参见图表 对象由计时器和处理程序保留。它将迅速增加 计时器,如果您正在创建和安排新任务。

正如 post 所暗示的那样,Handler 的使用非常简单。这是一个示例代码

import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.support.v7.app.AppCompatActivity;

public class TestActivity extends AppCompatActivity {


    private static int INITIAL_TIMER_DELAY = 100;
    private static int TIMER_PERIOD = 100;

    private android.os.Handler handler;
    private Runnable runnable;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        handler = new Handler(Looper.getMainLooper());
        runnable = new Runnable() {
            @Override
            public void run() {
                // Do something and reschedule ourself
                handler.postDelayed(this, TIMER_PERIOD);
            }
        };
        handler.postDelayed(runnable, INITIAL_TIMER_DELAY);

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        cancelTimer();
    }

    private void cancelTimer() {
        if (handler != null) {
            handler.removeCallbacks(runnable);
        }
    }

    private void rescheduleRunnable() {
        handler.postDelayed(runnable, INITIAL_TIMER_DELAY)
    }


}