TimerTask vs Thread.sleep vs Handler postDelayed - most accurate to call function every N milliseconds?
There are some disadvantages of using Timer
- It creates only single thread to execute the tasks and if a task
takes too long to run, other tasks suffer. - It does not handle
exceptions thrown by tasks and thread just terminates, which affects
other scheduled tasks and they are never run
ScheduledThreadPoolExecutor deals properly with all these issues and it does not make sense to use Timer.. There are two methods which could be of use in your case.. scheduleAtFixedRate(...) and scheduleWithFixedDelay(..)
class MyTask implements Runnable {
@Override
public void run() {
System.out.println("Hello world");
}
}
ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(1);
long period = 100; // the period between successive executions
exec.scheduleAtFixedRate(new MyTask(), 0, period, TimeUnit.MICROSECONDS);
long delay = 100; //the delay between the termination of one execution and the commencement of the next
exec.scheduleWithFixedDelay(new MyTask(), 0, delay, TimeUnit.MICROSECONDS);
PostDelayed or Thread with thread.sleep()
I think you're mixing up some concepts. Handler
's postDelayed()
indeed will run a Runnable
after some time lapse, but only once.
For what you want to do you've several choices:
- Sleeping the
Thread
is one of them. A disatvantage of this is that theThread
might cause an exception and this way your execution could become unstable. Also, you'll have just oneThread
and you won't free it up even if it's sleeping, so you're using resources that you might not need at a time. - Another approach is using an
AsyncTask
. This is recommended, however, for short tasks. If you plan running this task for a longer period of time,AsyncTask
is probably not a good choice. - You can run a background
Service
with aHandler
to update the UI. Depends on what you're trying to achieve. - You'll probably want to have a look at
ScheduledExecutorService
. It has a method calledscheduleAtFixedRate()
which will do exactly that, execute aRunnable
each X time specified by one of the parameters. More info here.
Repeat method in short time interval
Context
Take into account the fact the Android uses it's own implementation of java.
There is no Java Virtual Machine in the Android platform. Java
bytecode is not executed. Instead Java classes are compiled into a
proprietary bytecode format and run on Dalvik, a specialized virtual
machine (VM) designed specifically for Android. Unlike Java VMs, which
are stack machines, the Dalvik VM is a register-based architecture.
Comparison of Java and Android API
So what holds true for the java virtual machine may not necessarily reflect on Android's implementation.
As a rule of thumbs it's better to use whatever the Android API makes available.
Solution
I recommend using the Handler.
Especially if you want to update views.
Even the official Android tutorials recommends :
To move data from a background thread to the UI thread, use a Handler
that's running on the UI thread.
From the start Timer gets excluded.
There are some disadvantages of using Timer It creates only single
thread to execute the tasks and if a task takes too long to run, other
tasks suffer. It does not handle exceptions thrown by tasks and thread
just terminates, which affects other scheduled tasks and they are
never run
From this answer.
And from the Android docs:
A ThreadPoolExecutor (i.e. ScheduledThreadPoolExecutor) is preferable to Timer when multiple worker threads are needed, or when
the additional flexibility or capabilities of ThreadPoolExecutor
(which this class extends) are required.
When using the Handler i recommend reading through this tutorial if you want to avoid memory leaks.
If it wasn't the case of an UI update a ThreadPoolExecutor would have been better because they provide improved performance when executing large numbers of asynchronous tasks, due to reduced per-task invocation overhead.
Handler().postDelayed is now deprecated. What function to call instead?
You need to use the constructor with an explicit looper, for the Main thread Looper use Looper.getMainLooper()
Handler(Looper.getMainLooper()).postDelayed({
notifyDataSetChanged()
}, 100)
Wait for 5 seconds
just add one-liner with lambda
(new Handler()).postDelayed(this::yourMethod, 5000);
edit for clarification: yourMethod
refers to the method which you want to execute after 5000 milliseconds.
Android TimerTask not finish after app is closing
Assuming you want to stop it when the Activity is destroyed :
@Override
protected void onDestroy()
{
super.onDestroy();
yourTimer.cancel();
}
Or if you want to stop it when your activity is hidden :
@Override
protected void onStop()
{
super.onStop();
yourTimer.cancel();
}
According to the activity workflow, choose the best method where your timer has to be cancelled :
Where do I create and use ScheduledThreadPoolExecutor, TimerTask, or Handler?
I prefer to use ScheduledThreadPoolExecutor. Generally, if I understand your requirements correctly, all these can be implemented in your activity, TimerTask and Handler are not needed, see sample code below:
public class MyActivity extends Activity {
private ScheduledExecutorService scheduleTaskExecutor;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
scheduleTaskExecutor= Executors.newScheduledThreadPool(5);
// This schedule a task to run every 10 minutes:
scheduleTaskExecutor.scheduleAtFixedRate(new Runnable() {
public void run() {
// Parsing RSS feed:
myFeedParser.doSomething();
// If you need update UI, simply do this:
runOnUiThread(new Runnable() {
public void run() {
// update your UI component here.
myTextView.setText("refreshed");
}
});
}
}, 0, 10, TimeUnit.MINUTES);
} // end of onCreate()
}
Remember to finish/close your runnable task properly in Activity.onDestroy(), hope that help.
Related Topics
How to Convert Rgb Color to Int in Java
Passing Function as a Parameter in Java
Click Is Not Working on the Listitem Listview Android
Rotate Marker and Move Animation on Map Like Uber Android
How to Avoid Unnecessary Firestore Reads with Cache
Read/Write .Txt File with Special Characters
Why Ruby Modulo Is Different from Java/Other Lang
Call and Receive Output from Python Script in Java
How to Resume Android Activity Programmatically from Background
Recyclerview Scrolled Up/Down Listener
Android Calculate Days Between Two Dates
How to Implement the Android Actionbar Back Button
Kotlin-Android: Unresolved Reference Databinding