在方法Java中延迟执行代码

Con*_*use 6 java android delay jdk1.6

我希望在我的java(Android)程序中每2秒钟后连续生成一个随机数至少10分钟.但我只想暂停/延迟只在一种方法中执行代码而不是整个程序.

我试过像这样使用Thread -

boolean stop = false;
int random_number = 0;

while(true){
    if(stop){  //if stop becomes true, then
        return;  //terminate the method
    }

    random_number = Math.random(); //generate random number
                                   //which is used bu some other
                                   //part of code
    try {
        Thread.sleep(2000);        //delay the code for 2 secs
    } catch(InterruptedException ex) {  //and handle the exceptions
        Thread.currentThread().interrupt();
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,这不起作用 Thread.sleep停止整个程序执行而只是停止执行代码内部方法,我的整个屏幕变为空白.

我也试过使用,Handler但它不起作用,因为它不会停止我的方法中的代码执行,而只是堆叠.

这将证明它的工作更好 -

while(true){
    final Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            System.out.println("After 2 secs"); //this gets printed
                                               //later
        }
    }, 2000);
    System.out.println("Before 2 secs"); //this gets printed first
}
Run Code Online (Sandbox Code Playgroud)

所以代码堆叠使它等同于使用while循环并使其非常慢.

此外,由于我正在为Android开发app,我正在运行Java SE 6,因此我无法使用scheduleAtFixedRate.有没有其他方法可以实现这一目标?

非常感谢!

Ant*_*one 6

private Timer timer;
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                //Generate number
            }
        }, 2000, 2000);

//Documentation (From SDK)
/**
             * Schedule a task for repeated fixed-rate execution after a specific delay
             * has passed.
             *
             * @param task
             *            the task to schedule.
             * @param delay
             *            amount of time in milliseconds before first execution.
             * @param period
             *            amount of time in milliseconds between subsequent    executions.
    public void scheduleAtFixedRate(TimerTask task, long delay, long period) {
                if (delay < 0 || period <= 0) {
                    throw new IllegalArgumentException();
                }
                scheduleImpl(task, delay, period, true);
    }
Run Code Online (Sandbox Code Playgroud)

当你想要阻止它

timer.cancel()
Run Code Online (Sandbox Code Playgroud)


kam*_*uel 5

选项1:使用线程,您可以在主(UI)线程上运行您的作业:

new Thread(new Runnable() {
  // some code here ...

  // This might be in a loop.
  try {
    Thread.sleep(2000);
  } catch(InterruptedException ex) {
    // Handle ...
  }
 }
}).start();
Run Code Online (Sandbox Code Playgroud)

然后,如果这个新线程你想要修改UI(即显示/隐藏按钮,在屏幕上显示某些内容等),请记住通过UI线程传递它,因为只有这个可以修改UI.您可以考虑使用Activity.runOnUiThread().

选项2:另一种更接近Android问题的方式是使用AsyncTask.它包含三个回调,可用于在UI线程上进行工作.这样的代码草图可能如下所示:

 private class MyTask extends AsyncTask<Void, Void, Void> {
   protected Void doInBackground(Void... param) {
     // This method is running off the UI thread.
     // Safe to stop execution here.

     return null;
   }

   protected void onProgressUpdate(Void... progress) {
     // This methid is running on the UI thread. 
     // Do not stop thread here, but safe to modify the UI.
   }

   protected void onPostExecute(Long result) {
     // Also on UI thread, executed once doInBackground()
     // finishes.
   }
 }
Run Code Online (Sandbox Code Playgroud)

选项3:然后还有一个定时器,如@Stultuske所建议的那样.它不那么灵活AsyncTask,但为你处理间隔.


Fra*_*coC 5

根据您的需求,您仍然可以使用Handler完成您想要的。

您不必在while循环中创建/启动Handler(如您所注意到的,除非您停止循环本身,否则它只会堆积起来,但这是胡说八道)。

只需创建Handler并告诉他发布延迟的Runnable实例即可。最后,在Runnable中检查条件。如果仍然正常,则发布另一个可运行的延迟,否则您什么也不做,并且处理程序将不再执行。

final Handler handler = new Handler();
Runnable runnable = new Runnable() {

    @Override
    public void run() {
        System.out.println("After 2 secs");
        random_number = Math.random();

        if (!stop) // should not be stopped, so we add another runnable;
        {
          handler.postDelayed(this, 2000);
        }
   }

handler.postDelayed(runnable, 2000);
Run Code Online (Sandbox Code Playgroud)

唯一的缺点是,如果一段时间不使用该设备,则Handler可能会冻结,这意味着一旦打开设备屏幕,它将从其剩余位置开始倒数。

它可以完成1分钟的正确工作,然后在设备进入睡眠模式时阻塞1.4秒,一旦再次打开,Handler将执行剩余的0.6秒。

仍然,不知道您的需求,您可能不会受到这种行为的影响,答案可能适合您。