Every Android app has its own thread that runs UI objects, this thread is called Main Thread or UI Thread. If your app is running a background thread long operation and you want to publish the result in-app screen. But here is a problem, your app task is running in the background and Where UI Thread is different and only objects running on the UI Thread have to access other objects in UI Thread. So your background app task can’t communicate or send data directly to Main Thread (UI Thread). That time you have to use an Android Handler, that’s running on UI Thread.
In this tutorial, you will learn the following:
- Overview Android Handler
- Complete example Background thread communicate to the Main thread using Handler.
Android Handler allows you to communicate with the UI thread from other background threads. It’s useful in android as android doesn’t allow other threads to communicate directly with the UI thread.
Let’s Build an Android Handler example in kotlin:
In Android app development using kotlin language. In the example on Click button thread will run and update the UI counter and progress bar using Handler. You can see the counting in TextView label . Let’s see the steps to how to do it.
Step 1. Create a new project “Build Your First Android App in Kotlin“
Step 2. Add following code in “activity_main.xml” layout file
Where Button will start the thread and Textview show count and ProgressBar will show update progress.
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout 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" tools:context=".MainActivity"> <ProgressBar android:id="@+id/progressBar" style="?android:attr/progressBarStyleHorizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:layout_alignParentTop="true" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:layout_margin="8dp" android:layout_marginTop="120dp" android:text="Count" android:textSize="36sp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/progressBar" /> <Button android:id="@+id/start_progress" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_margin="16dp" android:layout_marginTop="156dp" android:text="Start" android:textSize="18sp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/textView" /> </android.support.constraint.ConstraintLayout>
Step 3. Open the “MainActivity.kt” and add following code
On clicking button – where we are updating ProgressBar and while updating ProgressBar same time updating TextView by using the same Handler.
package `in`.eyehunt.androidhandler import android.support.v7.app.AppCompatActivity import android.os.Bundle import android.os.Handler import android.os.Message import android.util.Log import kotlinx.android.synthetic.main.activity_main.* class MainActivity : AppCompatActivity() { lateinit var mHandlerThread: Handler lateinit var mThread: Thread override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) progressBar.max = 100 mThread = Thread(Runnable { for (i in 0..100) { Log.d("I", ":$i") progressBar.progress = i try { Thread.sleep(100) } catch (ex: InterruptedException) { ex.printStackTrace() } val message = Message() message.what = COUNT message.arg1 = i mHandlerThread.sendMessage(message) } }) // start counting start_progress.setOnClickListener { if (!mThread.isAlive) { val currentProgess = progressBar.progress mHandlerThread.sendEmptyMessage(START) } } } override fun onResume() { super.onResume() mHandlerThread = object : Handler() { override fun handleMessage(msg: Message) { super.handleMessage(msg) if (msg.what === START) { mThread.start() } else if (msg.what === COUNT) { textView.text = "Count " + msg.arg1 } } } } companion object { private const val START = 100 private const val COUNT = 101 } }
Step 4. Now Run the application, in an emulator or On you android device
Output screenshot Android Handler Dialog :
Download source code Android Handler in kotlin
https://github.com/EyeHunts/AndroidHandler
Note : This example (Project) is developed in Android Studio 3.1.3 . Tested on Android 9 ( Android-P), compile SDK version API 27: Android 8.0 (Oreo)
MinSdkVersion=”15″
TargetSdkVersion=”27″
Coding in Kotlin
Any suggestions always welcome, please do comment.