Search code examples
javaandroiddelayjava-6

Delay execution of code in method Java


I want to generate random number after every 2 seconds in my java (Android) program continuously for at least 10 minutes. But I just want to pause/delay execution of code in only one method and not the whole program.

I tried using Thread like this -

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();
    }
}

However, this doesn't work as Thread.sleep stop the whole program execution instead on just stopping execution of code inside method and my whole screen becomes blank.

I also tried using Handler but it didn't work either as it doesn't stop execution of code in my method and instead just stack up.

This will demonstrate the working of it better -

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
}

So the code stacks up making it equivalent to using while loop and make it incredibly slow.

Also, since I'm developing app for Android, I'm running on Java SE 6, so I can't use scheduleAtFixedRate. Is there any other way in which I can accomplish this?

Thanks a lot!


Solution

  • Option 1: Using threads, you might run your job off the main (UI) thread:

    new Thread(new Runnable() {
      // some code here ...
    
      // This might be in a loop.
      try {
        Thread.sleep(2000);
      } catch(InterruptedException ex) {
        // Handle ...
      }
     }
    }).start();
    

    Then, if this new thread you'd like to modify UI (i.e. show/hide button, display something on the screen etc), remember to pass that through the UI thread, as only this one can modify the UI. You might consider using Activity.runOnUiThread() for that.

    Option 2: Another, more Android-style way of approaching that issue is to use AsyncTask. It contains three callbacks which can be used to do work on- and off- the UI thread. Sketch of such a code could look like:

     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.
       }
     }
    

    Option 3: Then there is also a Timer, as suggested by @Stultuske. It's less flexible then AsyncTask, but handles the interval for you.