Android Pending Events

I am writing an Android application that plans certain ways to run at irregular intervals. As far as I know, there are at least two ways to do this:

  • use Handler.postDelayed to run Runnable after a given time.

  • use Timer to schedule and execute TimerTask after a specified time.

I am looking for a solution that can quickly trigger multiple events. Which method is best to use? Is there a better one that I miss?

+7
source share
2 answers

Short answer

Differences in how they work in the background, using the wrong one, can have terrible consequences.

All messages and runnables sent to the handler run in the same thread as the one that the handler created, often a service or activity thread.

A timer, on the other hand, creates a new thread.

It seems to me that the timer is the way for you, but you can’t say exactly with the information. It all boils down to the fact that if you want everything to work on one thread or several threads, both have their advantages and disadvantages.

Long answer

Handlers

From the documentation handler :

Each Handler instance is associated with one thread and this thread's message queue. When you create a new handler, it is attached to the thread / message queue of the thread that creates it - from this point it will deliver messages and executable files to the message queue and execute them as they exit the message queue.

This means that only one event can be processed at the same time as the handler, and all other messages / runnables must wait while another is running.
However, Handler is the only way to go if you want to manipulate the user interface since only the main user interface thread is allowed.

Using handlers can freeze your application if you do not care.
A common mistake is that people create a handler in the main UI thread, create a bunch of workflows and call heavy methods with handlers, this will block the main UI thread and make a scary “application not responding” dialog in android

These handlers can do great with thread safety, you can make each thread a handler that handles all calls with cross-threads (using messages), and if you make sure that only the handler modifies the object, you will never have thread problems.

Timers

With timers, however, you get overhead or create threads and add thread complexity, be careful when changing shared objects!

The advantage of concurrency is that if several tasks are to be performed at the same time (or in a very short period of time), the handlers may not be able to handle this, while the timers will be.

Other options

  • You might be able to use DelayQueue
  • If you want to allow the phone to sleep and have longer delays, use the AlarmManager
+8
source

I used a timer to delay the process of the event, during the delay period a new event for beginners will override the older one. So onTextChanged events will not be processed too many times when the user enters text fast enough.

 EditText editor_ Timer editorTimer_ editor_.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(final CharSequence s, int start, int before, int count) { try { /* events absorber technique */ if (editorTimer_!=null) { editorTimer_.cancel(); //dump the timer to cancel the previous onTextChange firing } //the timer is dumped, we must to create a new one editorTimer_ = new Timer(); //schedule a task which will be executed in 500ms if the timer won't canceled due //to other (possible future) onTextChanged event editorTimer_.schedule(new TimerTask() { @Override public void run() { try { /* * do whatever onTextChanged event have to do. But it should be quick * heavy process must be executed on other thread */ if (TextUtils.isEmpty(s)) { ... } else { ... } } catch (Exception ex) { Log.w(TAG, ex.toString()); } } }, 500); //the 500ms delay is here } catch (Exception ex) { Log.w(TAG, ex.toString()); } } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void afterTextChanged(Editable s) { } }); 
+2
source

All Articles