Question

[Solved] How to run a Runnable thread in Android at defined intervals?

I developed an application to display some text at defined intervals in the Android emulator screen. I am using the Handler class. Here is a snippet from my code:

handler = new Handler();
Runnable r = new Runnable() {
    public void run() {
        tv.append("Hello World");               
    }
};
handler.postDelayed(r, 1000);

When I run this application the text is displayed only once. Why?

Solution #1:

The simple fix to your example is :

handler = new Handler();

final Runnable r = new Runnable() {
    public void run() {
        tv.append("Hello World");
        handler.postDelayed(this, 1000);
    }
};

handler.postDelayed(r, 1000);

Or we can use normal thread for example (with original Runner) :

Thread thread = new Thread() {
    @Override
    public void run() {
        try {
            while(true) {
                sleep(1000);
                handler.post(this);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
};

thread.start();

You may consider your runnable object just as a command that can be sent to the message queue for execution, and handler as just a helper object used to send that command.

More details are here http://developer.android.com/reference/android/os/Handler.html

Respondent: alex2k8

Solution #2:

new Handler().postDelayed(new Runnable() {
    public void run() {
        // do something...              
    }
}, 100);
Respondent: user2212515

Solution #3:

I think can improve first solution of Alex2k8 for update correct each second

1.Original code:

public void run() {
    tv.append("Hello World");
    handler.postDelayed(this, 1000);
}

2.Analysis

  • In above cost, assume tv.append("Hello Word") cost T milliseconds, after display 500 times delayed time is 500*T milliseconds
  • It will increase delayed when run long time

3. Solution

To avoid that Just change order of postDelayed(), to avoid delayed:

public void run() {
    handler.postDelayed(this, 1000);
    tv.append("Hello World");
}
Respondent: NguyenDat

Solution #4:

For repeating task you can use

new Timer().scheduleAtFixedRate(task, runAfterADelayForFirstTime, repeaingTimeInterval);

call it like

new Timer().scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {

            }
        },500,1000);

The above code will run first time after half second(500) and repeat itself after each second(1000)

Where

task being the method to be executed

after the time to initial execution

(interval the time for repeating the execution)

Secondly

And you can also use CountDownTimer if you want to execute a Task number of times.

    new CountDownTimer(40000, 1000) { //40000 milli seconds is total time, 1000 milli seconds is time interval

     public void onTick(long millisUntilFinished) {
      }
      public void onFinish() {
     }
    }.start();

//Above codes run 40 times after each second

And you can also do it with runnable. create a runnable method like

Runnable runnable = new Runnable()
    {
        @Override
        public void run()
        {

        }
    };

And call it in both these ways

new Handler().postDelayed(runnable, 500 );//where 500 is delayMillis  // to work on mainThread

OR

new Thread(runnable).start();//to work in Background 
Respondent: AndroidGeek

Solution #5:

I believe for this typical case, i.e. to run something with a fixed interval, Timer is more appropriate. Here is a simple example:

myTimer = new Timer();
myTimer.schedule(new TimerTask() {          
@Override
public void run() {
    // If you want to modify a view in your Activity
    MyActivity.this.runOnUiThread(new Runnable()
        public void run(){
            tv.append("Hello World");
        });
    }
}, 1000, 1000); // initial delay 1 second, interval 1 second

Using Timer has few advantages:

  • Initial delay and the interval can be easily specified in the schedule function arguments
  • The timer can be stopped by simply calling myTimer.cancel()
  • If you want to have only one thread running, remember to call myTimer.cancel() before scheduling a new one (if myTimer is not null)
Respondent: iTech

Solution #6:

Handler handler=new Handler();
Runnable r = new Runnable(){
    public void run() {
        tv.append("Hello World");                       
        handler.postDelayed(r, 1000);
    }
}; 
handler.post(r);
Respondent: singh arjun

Solution #7:

If I understand correctly the documentation of Handler.post() method:

Causes the Runnable r to be added to the message queue. The runnable will be run on the thread to which this handler is attached.

So examples provided by @alex2k8, even though are working correctly, are not the same.
In case, where Handler.post() is used, no new threads are created. You just post Runnable to the thread with Handler to be executed by EDT.
After that, EDT only executes Runnable.run(), nothing else.

Remember:
Runnable != Thread.

Respondent: Damian Walczak

Solution #8:

Kotlin

private lateinit var runnable: Runnable
override fun onCreate(savedInstanceState: Bundle?) {
    val handler = Handler()
    runnable = Runnable {
        // do your work
        handler.postDelayed(runnable, 2000)
    }
    handler.postDelayed(runnable, 2000)
}

Java

Runnable runnable;
Handler handler;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    handler = new Handler();
    runnable = new Runnable() {
        @Override
        public void run() {
            // do your work
            handler.postDelayed(this, 1000);
        }
    };
    handler.postDelayed(runnable, 1000);
}
Respondent: Khemraj

Solution #9:

An interesting example is you can continuously see a counter/stop-watch running in separate thread. Also showing GPS-Location. While main activity User Interface Thread is already there.

Excerpt:

try {    
    cnt++; scnt++;
    now=System.currentTimeMillis();
    r=rand.nextInt(6); r++;    
    loc=lm.getLastKnownLocation(best);    

    if(loc!=null) { 
        lat=loc.getLatitude();
        lng=loc.getLongitude(); 
    }    

    Thread.sleep(100); 
    handler.sendMessage(handler.obtainMessage());
} catch (InterruptedException e) {   
    Toast.makeText(this, "Error="+e.toString(), Toast.LENGTH_LONG).show();
}

To look at code see here:

Thread example displaying GPS Location and Current Time runnable alongside main-activity’s User Interface Thread

Solution #10:

Kotlin with Coroutines

In Kotlin, using coroutines you can do the following:

CoroutineScope(Dispatchers.Main).launch { // Main, because UI is changed
    ticker(delayMillis = 1000, initialDelayMillis = 1000).consumeEach {
        tv.append("Hello World")
    }
}

Try it out here!

Respondent: Willi Mentzel

Solution #11:

now in Kotlin you can run threads this way:

class SimpleRunnable: Runnable {
    public override fun run() {
        println("${Thread.currentThread()} has run.")
    }
}
fun main(args: Array<String>) {
    val thread = SimpleThread()
    thread.start() // Will output: Thread[Thread-0,5,main] has run.
    val runnable = SimpleRunnable()
    val thread1 = Thread(runnable)
    thread1.start() // Will output: Thread[Thread-1,5,main] has run
}
Respondent: André Abboud

The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 .

Most Popular

To Top
India and Pakistan’s steroid-soaked rhetoric over Kashmir will come back to haunt them both clenbuterol australia bossier man pleads guilty for leadership role in anabolic steriod distribution conspiracy