<p>In this article, we will talk about what is thread and how to create a separate worker thread in our android application to achieve asynchronous processing with a basic example.</p>
<h3><strong><span style="color: #000080;">Thread</span></strong></h3>
<p>Android follows a multitasking design. This allows a number of applications to run at the same time. Let&#8217;s say you are playing a song in Ganna app and you are typing something on WhatsApp at the same time. You are using two tasks at the same time which we called as multitasking. But let&#8217;s say if we talk about one <strong><span style="color: #008000;">task/process/App</span></strong> i.e WhatsApp then in WhatsApp, parallelly while you are typing a word at the same time it is showing some words related to what you are typing and this is achieved by making use of <span style="color: #0000ff;"><strong>threads</strong></span>.</p>
<p>A thread is a lightweight subprocess, the smallest unit of processing. It is a separate path of execution.</p>
<p>Threads are independent. If there occurs exception in one thread, it doesn&#8217;t affect other threads.</p>
<p><img class="alignnone size-full wp-image-1198" src="https://c1ctech.com/wp-content/uploads/2019/08/Screenshot-2019-08-26-15.31.16.png" alt="Screenshot 2019-08-26 15.31.16" width="1446" height="624" />As shown in the above figure, At runtime, an Android operating system is always hosting an app as a process. So each app gets a dedicated process to run itself. At any point in time, it can host any no. of apps and for each app, you have a separate process. If you consider one particular process then there can be any no. of threads inside it and one of the thread is Main thread (default thread comes with every application) or also referred to as UI thread. In this thread, all of your UI tasks are getting executed like rendering a button, click of a button, everything that is related to UI happens in this particular thread.</p>
<p>Android supports the usage of the <span style="color: #008000;"><strong>Thread</strong></span> class to perform asynchronous processing. Thread class provides constructors and methods to create and perform operations on a thread. Thread class extends <span style="color: #000000;"><strong>Object</strong></span> class and implements <strong>Runnable</strong> interface.</p>
<p>Always remember the two most important rules when working with threads:</p>
<ul>
<li>Don’t block the Main thread</li>
<li>Don’t try and access the UI directly from the worker thread</li>
</ul>
<h4><strong><span style="color: #000080;">Whats the need of a thread or why we use Threads?</span></strong></h4>
<ul>
<li>To perform asynchronous or background processing</li>
<li>Increases the responsiveness of GUI applications</li>
<li>Take advantage of multiprocessor systems</li>
<li>Simplify program logic when there are multiple independent entities</li>
</ul>
<h3><strong><span style="color: #000080;">The Application Main Thread</span></strong></h3>
<p>All apps, when started, run in a single Main thread. It’s also known as the User Interface (or UI) thread.</p>
<p>Android modifies the user interface and handles input events from this <em>main thread</em>. Android collects all events in this thread in a queue and processes this queue with an instance of the <code>Looper</code> class.</p>
<p><img class="alignnone size-full wp-image-1200" src="https://c1ctech.com/wp-content/uploads/2019/08/Screenshot-2019-08-26-18.59.57.png" alt="Screenshot 2019-08-26 18.59.57" width="1548" height="676" /></p>
<p>By default, all components (Activities, Services, Content provider, Broadcast receivers&#8230;) of the same application run in the same process and thread (called the &#8220;main&#8221; thread).</p>
<p><img class="aligncenter size-full wp-image-1199" src="https://i0.wp.com/c1ctech.com/wp-content/uploads/2019/08/Screenshot-2019-08-26-18.16.58-1-2279880879-1566823954707.png?ssl=1&;w=612" alt="Screenshot 2019-08-26 18.16.58 (1)" width="306" height="545" /></p>
<p>When we try to execute long-running operations in our application by default they are called in the main thread and are called synchronously, which means that the UI will remain completely unresponsive until the operation completes. Running long operations on the app&#8217;s main thread will freeze the app&#8217;s user interface and after a couple seconds, we get an &#8220;<strong><span style="color: #008000;">application not responding</span></strong>&#8221; dialog message with the option to force quit the app.</p>
<p>For example, let us consider the below code:</p>
<pre>public class MainActivity extends AppCompatActivity {

 private static final String TAG = "MainActivity";


 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);


 }

 public void startThread(View view) {

 for (int i = 1; i <;= 10; i++) {

 Log.d(TAG, "startThread: " + i);

 try {
 Thread.sleep(1000);
 } catch (InterruptedException e) {
 e.printStackTrace();
 }
 }

 }
}</pre>
<p>In the above code on clicking the <strong>start</strong> button, the <span style="color: #008000;"><strong>startThread</strong></span> method will be called. This method will print the log statement after every one second, ten times.</p>
<p>By default, this method will be called inside the main thread, synchronously and it will freeze the app until the operation is finished. So in between, if we will try to interact with other UI events (on/off switch) we get an &#8220;<strong>application not responding</strong>&#8221; dialog message with the options <strong><span style="color: #008000;">close app</span></strong> and <strong><span style="color: #008000;">wait</span></strong> like this:</p>
<p><img class="alignnone wp-image-1203" src="https://c1ctech.com/wp-content/uploads/2019/08/Screenshot_1566840402-576x1024.png" alt="Screenshot_1566840402" width="266" height="473" /> <img class="alignnone wp-image-1201" src="https://c1ctech.com/wp-content/uploads/2019/08/Screenshot_1566840475.png" alt="Screenshot_1566840475" width="267" height="475" /></p>
<h4><strong><span style="color: #000080;"> What triggers the ANR dialog?</span></strong></h4>
<ul>
<li>If an app can’t respond to user input within 5 seconds</li>
<li>If Broadcast receivers haven’t finished executing within 10 seconds</li>
</ul>
<p>To avoid this we have to move heavy operations like Network operations and database calls, as well as loading of certain components onto a separate <strong><span style="color: #008000;">thread</span></strong>. A separate thread will avoid blocking the UI while they are being performed (i.e., they are performed asynchronously from the UI).</p>
<h3><strong><span style="color: #000080;">Creating New Thread</span></strong></h3>
<p>Thread implementation can be achieved in two ways:</p>
<ol>
<li>Extending the Thread class</li>
<li>Implementing the Runnable Interface</li>
</ol>
<h4><strong><span style="color: #0000ff;">1) By extending Thread class</span></strong></h4>
<ul>
<li>The class should extend the Thread class.</li>
<li>The class should override the <span style="color: #008000;"><strong>run()</strong></span> method.</li>
<li>The functionality that is expected by the Thread to be executed is written in the run() method.</li>
<li>To start the thread, create a new Thread object and then call <span style="color: #008000;"><strong>start()</strong></span>.</li>
</ul>
<p><strong><span style="color: #0000ff;">void start()</span></strong>: Creates a new thread and makes it runnable.<br />
<strong><span style="color: #0000ff;">void run()</span></strong>: The new thread begins its life inside this method.</p>
<p><strong><span style="color: #0000ff;">Example:</span></strong></p>
<pre>public class MainActivity extends AppCompatActivity {

 private static final String TAG = "MainActivity";


 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 }

 public void startThread(View view) {

 ExampleThread thread = new ExampleThread(10);

 thread.start();
 }

 class ExampleThread extends Thread {


 int seconds;


 ExampleThread(int seconds) {

 this.seconds = seconds;
 }

 @Override
 public void run() {

 for (int i = 1; i <;= seconds; i++) {

 Log.d(TAG, "startThread: " + i);

 try {
 Thread.sleep(1000);
 } catch (InterruptedException e) {
 e.printStackTrace();
 }
 }
 }

 }
}

</pre>
<p><span style="color: #0000ff;"><strong>Output:</strong></span></p>
<p><img class="alignnone size-full wp-image-1204" src="https://c1ctech.com/wp-content/uploads/2019/08/Screenshot-2019-08-26-23.53.10.png" alt="Screenshot 2019-08-26 23.53.10" width="1392" height="314" /></p>
<h4></h4>
<h4><strong><span style="color: #0000ff;">2) By implementing Runnable interface</span></strong></h4>
<ul>
<li>The class should implement the Runnable interface</li>
<li>The class should override the <strong><span style="color: #008000;">run()</span></strong> method.</li>
<li>The functionality that is expected by the Thread to be executed is put in the run() method</li>
<li>To start the thread, pass the runnable to a new Thread object and then call <strong><span style="color: #008000;">start()</span></strong>.</li>
</ul>
<p><strong><span style="color: #000080;">Example:</span></strong></p>
<pre>public class MainActivity extends AppCompatActivity {

 private static final String TAG = "MainActivity";


 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 }

 public void startThread(View view) {

 ExampleRunnable runnable = new ExampleRunnable(10);
 new Thread(runnable).start();

 }

 class ExampleRunnable implements Runnable {

 int seconds;
 
 ExampleRunnable(int seconds) {

 this.seconds = seconds;

 }


 @Override
 public void run() {

 for (int i = 1; i <;= seconds; i++) {

 Log.d(TAG, "startThread: " + i);

 try {
 Thread.sleep(1000);
 } catch (InterruptedException e) {
 e.printStackTrace();
 }
 }
 }
 }
}

</pre>
<h3><strong><span style="color: #000080;">Extends Thread class vs Implements Runnable Interface</span></strong></h3>
<ul>
<li>Extending the <span style="color: #008000;"><strong>Thread</strong></span> class will make your class unable to extend other classes, because of the single inheritance feature in JAVA. However, this will give you a simpler code structure. If you implement <strong><span style="color: #008000;">Runnable</span></strong>, you can gain better object-oriented design and consistency and also avoid the single inheritance problems.</li>
<li>If you just want to achieve basic functionality of a thread you can simply implement Runnable interface and override <strong><span style="color: #008000;">run()</span></strong> method. But if you want to do something serious with thread object as it has other methods like <strong>suspend(), resume(), ..etc</strong> which are not available in Runnable interface then you may prefer to extend the Thread class.</li>
</ul>
<h3 class="p1"><span style="color: #000080;"><b>Worker threads</b></span></h3>
<p class="p2">According to the <strong><span style="color: #008000;">single-threaded model</span></strong> described above, it&#8217;s important to the responsiveness of your application&#8217;s UI that you do not block the UI thread. If you have operations to perform that are not instantaneous, you should make sure to do them in separate threads (&#8220;background&#8221; or &#8220;worker&#8221; threads).</p>
<p class="p2">The other rule says, that you cannot update the UI from any thread other than the UI thread or the &#8220;main&#8221; thread.</p>
<p><strong><span style="color: #0000ff;">For example:</span></strong></p>
<pre>public class MainActivity extends AppCompatActivity {

 private static final String TAG = "MainActivity";
 Button btn_start;


 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 btn_start = findViewById(R.id.btn_start);

 }

 public void startThread(View view) {
 ExampleThread thread = new ExampleThread(10);

 thread.start();
 }

 class ExampleThread extends Thread {


 int seconds;


 ExampleThread(int seconds) {

 this.seconds = seconds;
 }

 @Override
 public void run() {

 for (int i = 1; i <;= seconds; i++) {

 if (i == 5) {
 btn_start.setText("50%");
 }

 Log.d(TAG, "startThread: " + i);

 try {
 Thread.sleep(1000);
 } catch (InterruptedException e) {
 e.printStackTrace();
 }
 }
 }

 }</pre>
<p>In the above example, the <strong>ExampleThread</strong> will execute the log statement up to i equals to 4 and when i equals to 5 our app will crash.</p>
<p>In logcat, you can see the error message : <span style="color: #ff0000;"><strong>Only the original thread that created a view hierarchy can touch its views.</strong></span>It clearly says that you cannot update the UI from any thread other than the UI thread.</p>
<p class="p2">To fix this problem, Android offers several ways to access the UI thread from other threads. Here is a list of methods that can help:</p>
<!-- WP QUADS Content Ad Plugin v. 2.0.98.1 -->
<div class="quads-location quads-ad2" id="quads-ad2" style="float:none;margin:0px;">

</div>

<ul class="ul1">
<li class="li3"><strong><span class="s1" style="color: #0000ff;"><span class="s2">Activity.runOnUiThread(Runnable)</span></span></strong></li>
<li class="li3"><strong><span class="s1" style="color: #0000ff;"><span class="s2">View.post(Runnable)</span></span></strong></li>
<li class="li3"><strong><span class="s1" style="color: #0000ff;"><span class="s2">View.postDelayed(Runnable, long)</span></span></strong></li>
</ul>
<p>For example, by using <span style="color: #008000;"><strong><span class="s1"><span class="s2">View.post(Runnable) </span></span></strong></span><span class="s1" style="color: #000000;"><span class="s2">you can access the UI Thread inside other Thread(i.e ExampleThread) as shown below:</span></span></p>
<pre>public class MainActivity extends AppCompatActivity {

 private static final String TAG = "MainActivity";
 Button btn_start;


 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 btn_start = findViewById(R.id.btn_start);

 }

 public void startThread(View view) {
 ExampleThread thread = new ExampleThread(10);

 thread.start();
 }

 class ExampleThread extends Thread {


 int seconds;


 ExampleThread(int seconds) {

 this.seconds = seconds;
 }

 @Override
 public void run() {

 for (int i = 1; i <;= seconds; i++) {

 if (i == 5) {
 btn_start.post(new Runnable() {
 @Override
 public void run() {
 btn_start.setText("50%");
 }
 });

 }

 Log.d(TAG, "startThread: " + i);

 try {
 Thread.sleep(1000);
 } catch (InterruptedException e) {
 e.printStackTrace();
 }
 }
 }

 }</pre>
<h3></h3>
<h3><strong><span style="color: #000080;">Thread Basic Example</span></strong></h3>
<p>Let&#8217;s create a new android application to understand the concept of asynchronous processing in Android applications.</p>
<ol>
<li>Create a new android application <span style="color: #008000;"><strong>Threadexample.</strong></span></p>
</li>
<li>Open layout file <strong><span style="color: #008000;">activity_main</span></strong> and write the below code. This file consists of one <strong>Imageview</strong> and one <strong>button</strong>.</p>
</li>
</ol>
<p><span style="color: #0000ff;"><strong>activity_main.xml</strong></span></p>
<pre><;?xml version="1.0" encoding="utf-8"?>;
<;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:app="http://schemas.android.com/apk/res-auto"
 xmlns:tools="http://schemas.android.com/tools"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:gravity="center"
 android:orientation="vertical"
 tools:context=".MainActivity">;
 
 <;ImageView
 android:id="@+id/image"
 android:layout_width="350dp"
 android:layout_height="350dp"
 android:background="@drawable/border_image"/>;

 <;Button
 android:id="@+id/btn_download"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_marginTop="10dp"
 android:background="@android:color/holo_blue_bright"
 android:onClick="downloadImage"
 android:padding="10dp"
 android:text="download image"
 android:textColor="@android:color/black"
 android:textStyle="bold" />;


<;/LinearLayout>;</pre>
<p>3 . Open <span style="color: #008000;"><strong>MainActivity.java</strong></span> and write the below code:</p>
<p><span style="color: #0000ff;"><strong>MainActivity.java</strong></span></p>
<pre class="p1"><span class="s1"><b>package </b></span><span class="s2">trendlife.threadexample;</span>

<span class="s1"><b>import </b></span><span class="s2">android.app.Activity;</span>

<span class="s1"><b>import </b></span><span class="s2">android.graphics.Bitmap;</span>

<span class="s1"><b>import </b></span><span class="s2">android.graphics.BitmapFactory;</span>

<span class="s1"><b>import </b></span><span class="s2">android.os.Bundle;</span>

<span class="s1"><b>import </b></span><span class="s2">android.support.v7.app.AppCompatActivity;</span>

<span class="s1"><b>import </b></span><span class="s2">android.util.Log;</span>

<span class="s1"><b>import </b></span><span class="s2">android.view.View;</span>

<span class="s1"><b>import </b></span><span class="s2">android.widget.ImageView;</span>

<span class="s1"><b>import </b></span><span class="s2">android.widget.Toast;</span>

<span class="s1"><b>import </b></span><span class="s2">java.io.IOException;</span>

<span class="s1"><b>import </b></span><span class="s2">java.io.InputStream;</span>

<span class="s1"><b>import </b></span><span class="s2">java.net.HttpURLConnection;</span>

<span class="s1"><b>import </b></span><span class="s2">java.net.MalformedURLException;</span>

<span class="s1"><b>import </b></span><span class="s2">java.net.URL;</span>

<span class="s1"><b>public class </b></span><span class="s2">MainActivity </span><span class="s1"><b>extends </b></span><span class="s2">AppCompatActivity {</span>

<span class="s2"><span class="Apple-converted-space"> </span>ImageView </span><span class="s3"><b>imageView</b></span><span class="s2">;</span>

<span class="s4"><span class="Apple-converted-space"> </span></span><span class="s2">@Override</span>

<span class="s5"><span class="Apple-converted-space"> </span></span><span class="s1"><b>protected void </b></span><span class="s2">onCreate(Bundle savedInstanceState) {</span>

<span class="s2"><span class="Apple-converted-space"> </span></span><span class="s1"><b>super</b></span><span class="s2">.onCreate(savedInstanceState);</span>

<span class="s2"><span class="Apple-converted-space"> </span>setContentView(R.layout.</span><span class="s3"><b><i>activity_main</i></b></span><span class="s2">);</span>

<span class="s2"><span class="Apple-converted-space"> </span></span><span class="s3"><b>imageView </b></span><span class="s2">= findViewById(R.id.</span><span class="s3"><b><i>image</i></b></span><span class="s2">);</span>

<span class="s2"><span class="Apple-converted-space"> </span>}</span>

<span class="s2"><span class="Apple-converted-space"> </span></span><span class="s1"><b>public void </b></span><span class="s2">downloadImage(View view) {</span>

<span class="s2"><span class="Apple-converted-space"> </span>Log.<i>i</i>(</span><span class="s6"><b>"Button"</b></span><span class="s2">, </span><span class="s6"><b>"Tapped"</b></span><span class="s2">);</span>

<span class="s2"><span class="Apple-converted-space"> </span>DownloadImage downloadImage = </span><span class="s1"><b>new </b></span><span class="s2">DownloadImage(</span><span class="s1"><b>this</b></span><span class="s2">);</span>

<span class="s2"><span class="Apple-converted-space"> </span></span><span class="s1"><b>new </b></span><span class="s2">Thread(downloadImage).start();</span>

<span class="s2"><span class="Apple-converted-space"> </span>}</span>

<span class="s2"><span class="Apple-converted-space"> </span></span><span class="s1"><b>class </b></span><span class="s2">DownloadImage </span><span class="s1"><b>implements </b></span><span class="s2">Runnable {</span>

<span class="s2"><span class="Apple-converted-space"> </span>Activity </span><span class="s3"><b>activity</b></span><span class="s2">;</span>

<span class="s2"><span class="Apple-converted-space"> </span>Bitmap </span><span class="s3"><b>result </b></span><span class="s2">= </span><span class="s1"><b>null</b></span><span class="s2">;</span>

<span class="s2"><span class="Apple-converted-space"> </span>DownloadImage(Activity activity) {</span>

<span class="s2"><span class="Apple-converted-space"> </span></span><span class="s1"><b>this</b></span><span class="s2">.</span><span class="s3"><b>activity </b></span><span class="s2">= activity;</span>

<span class="s2"><span class="Apple-converted-space"> </span>}</span>

<span class="s4"><span class="Apple-converted-space"> </span></span><span class="s2">@Override</span>

<span class="s5"><span class="Apple-converted-space"> </span></span><span class="s2"><b>public void </b></span><span class="s4">run() {</span>

<span class="s2"><span class="Apple-converted-space"> </span>URL url;</span>

<span class="s2"><span class="Apple-converted-space"> </span>HttpURLConnection httpURLConnection;</span>

<span class="s2"><span class="Apple-converted-space"> </span></span><span class="s1"><b>try </b></span><span class="s2">{</span>

<span class="s4"><span class="Apple-converted-space"> </span>url = </span><span class="s1"><b>new </b></span><span class="s4">URL(</span><span class="s2"><b>"https://vignette.wikia.nocookie.net/disney/images/0/0a/ElsaPose.png/revision/latest?cb=20170221004839"</b></span><span class="s4">);</span>

<span class="s2"><span class="Apple-converted-space"> </span>httpURLConnection = (HttpURLConnection) url.openConnection();</span>

<span class="s2"><span class="Apple-converted-space"> </span>httpURLConnection.connect();</span>

<span class="s2"><span class="Apple-converted-space"> </span>InputStream in = httpURLConnection.getInputStream();</span>

<span class="s2"><span class="Apple-converted-space"> </span></span><span class="s3"><b>result </b></span><span class="s2">= BitmapFactory.<i>decodeStream</i>(in);</span>

<span class="s2"><span class="Apple-converted-space"> </span>} </span><span class="s1"><b>catch </b></span><span class="s2">(MalformedURLException e) {</span>

<span class="s2"><span class="Apple-converted-space"> </span>e.printStackTrace();</span>

<span class="s2"><span class="Apple-converted-space"> </span>} </span><span class="s1"><b>catch </b></span><span class="s2">(IOException e) {</span>

<span class="s2"><span class="Apple-converted-space"> </span>e.printStackTrace();</span>

<span class="s2"><span class="Apple-converted-space"> </span>}</span>

<span class="s2"><span class="Apple-converted-space"> </span></span><span class="s3"><b>activity</b></span><span class="s2">.runOnUiThread(</span><span class="s1"><b>new </b></span><span class="s2">Runnable() {</span>

<span class="s2"><span class="Apple-converted-space"> </span></span><span class="s5">@Override</span>

<span class="s2"><span class="Apple-converted-space"> </span></span><span class="s1"><b>public void </b></span><span class="s4">run() {</span>

<span class="s2"><span class="Apple-converted-space"> </span></span><span class="s3"><b>imageView</b></span><span class="s2">.setImageBitmap(</span><span class="s3"><b>result</b></span><span class="s2">);</span>

<span class="s2"><span class="Apple-converted-space"> </span>Toast.<i>makeText</i>(</span><span class="s3"><b>activity</b></span><span class="s2">, </span><span class="s6"><b>"Image downloaded"</b></span><span class="s2">, Toast.</span><span class="s3"><b><i>LENGTH_SHORT</i></b></span><span class="s2">).show();</span>

<span class="s2"><span class="Apple-converted-space"> </span>}</span>

<span class="s2"><span class="Apple-converted-space"> </span>});</span>

<span class="s2"><span class="Apple-converted-space"> </span>}</span>

<span class="s2"><span class="Apple-converted-space"> </span>}</span>

<span class="s2">}</span></pre>
<p> ;</p>
<p>4 . Inside MainActivity, on <strong><span style="color: #008000;">DOWNLOAD IMAGE</span></strong> button click <strong><span style="color: #008000;">downloadImage</span></strong>() method will call. This method starts a new thread <span style="color: #008000;"><strong>DownloadImage</strong></span>.</p>
<p>5 . <strong><span style="color: #008000;">DownloadImage</span></strong> Thread downloading an image over the network and displaying it in an ImageView and then display a toast message <span style="color: #008000;"><strong>Image Downloaded</strong></span>.</p>
<p>6 . Open <strong><span style="color: #008000;">AndroidManifest</span></strong> file and add <strong><span style="color: #008000;">INTERNET</span></strong> permission to download an image over the network.</p>
<p><span style="color: #0000ff;"><strong><span style="color: #0000ff;">AndroidManifest.xml</span></strong></span></p>
<pre><;uses-permission android:name="android.permission.INTERNET"/>;</pre>
<p>7 . On running the android application <span style="color: #008000;"><strong>Threadexample</strong></span> it will look like this as shown below:</p>
<p><img class="alignnone wp-image-1205" src="https://c1ctech.com/wp-content/uploads/2019/08/Screenshot_1566898859.png" alt="Screenshot_1566898859" width="360" height="640" /></p>
<p>I hope this article will help you in understanding what is thread, why we use thread and how to use thread in our android applications. As we know it is possible to access UI components inside the worker thread using some of the methods which we have discussed above but there is one more alternative in android i.e <strong class="kp lf"><span style="color: #008000;">Handler</span> </strong>which also allows you communicate back with the UI thread from other background thread. In the next article, we will talk about <span style="color: #0000ff;"><strong>Handler</strong></span> in brief.

