Handler in Android
Main Thread
Android
handles all the UI operations and input events from one single thread which is
known as called the Main or UI thread. Android collects all events in this
thread in a queue and processes this queue with an instance of the Looper
class.
Android
supports Thread class to perform asynchronous processing. Android also supplies
java.util.concurrent package to perform background task like using the
ThreadPools and Executor classes.
Why Handler
If
you need to update the UI from another main Thread, you need to synchronize
with the main thread. Because of this restrictions and complexity, Android provides
additional constructed classes to handle concurrently in comparison with
standard Java i.e. Handler or AsyncTask.
A Handler
allows communicating back with UI thread from other background thread. This is
useful in android as android doesn’t allow other threads to communicate
directly with UI thread.
A
Handler allows you to send and process
Message and Runnable objects
associated with a thread's MessageQueue. Each Handler instance is associated
with a single thread and that thread's message queue.
When
you create a new Handler, it is bound to the thread / message queue of the
thread that is creating it -- from that point on, it will deliver messages and
runnables to that message queue and execute them as they come out of the
message queue.
There
are two main uses for a Handler:
(1)
To schedule messages and runnables to be
executed as some point in the future. In other words perform action on same
thread in future.
(2) To enqueue an action to be performed on a
different thread than your own. In other words enqueue an action to perform on different
thread.
How to
schedule
Scheduling
messages is accomplished with the post(Runnable), postAtTime(Runnable, long),
postDelayed(Runnable, long), sendEmptyMessage(int), sendMessage(Message),
sendMessageAtTime(Message, long), and sendMessageDelayed(Message, long)
methods.
The
post versions allow you to enqueue
Runnable objects to be called by the message queue when they are received.
The
sendMessage versions allow you to
enqueue a Message object containing a bundle of data that will be processed
by the Handler's handleMessage(Message) method (requiring that you implement a
subclass of Handler).
Difference
between post() and sendMessage()
Conventionally
you use post() when you want to
execute some code on the UI Thread without having to know anything about your
Handler object. It makes sense in many cases where arbitrary code needs to be
executed on the UI Thread.
But
in some cases you want to organize what is being sent to the UI Thread and have
specific functions you want to execute that way you can use sendMessage().
Example
Below
are the code snipped explains use of Handler’s post() method-
Android
Activity Layout (activity_main.xml)
<?xml version="1.0"
encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/click_start_button" />
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:indeterminate="false"
android:max="10" />
<Button
android:id="@+id/buttonStart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/start" />
</LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/click_start_button" />
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:indeterminate="false"
android:max="10" />
<Button
android:id="@+id/buttonStart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/start" />
</LinearLayout>
Android Activity (MainActivity.java)
import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.view.View; import android.widget.Button; import android.widget.ProgressBar; public class MainActivity extends Activity implements View.OnClickListener { private Handler mHandler; private ProgressBar mProgressBar; private Button mStartButton; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mHandler = new Handler(); mProgressBar = (ProgressBar) findViewById(R.id.progressBar); mStartButton = (Button) findViewById(R.id.buttonStart); mStartButton.setOnClickListener(this); } @Override public void onClick(View view) { switch (view.getId()) { case R.id.buttonStart: startProgress(); break; } } private void startProgress() { // New thread to perform background operation new Thread(new Runnable() { @Override public void run() { for (int i = 0; i <= 30; i++) { final int currentProgressCount = i; try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } // Update the value background thread to UI thread mHandler.post(new Runnable() { @Override public void run() { mProgressBar.setProgress(currentProgressCount); } }); } } }).start(); } }
For
more detail on Handler please refer -
To find more interesting topics on Software development follow me at https://medium.com/@ankit.sinhal
You can also find my Android Applications on play store
Comments
Post a Comment