Simplify Background Tasks in Android with Kotlin Coroutines: A Practical Example

Farman Ullah Marwat
3 min readJun 29, 2024

--

Android’s traditional AsyncTask has been deprecated, and it's time to embrace Kotlin coroutines for handling background tasks. In this article, we'll demonstrate how to use a custom AsyncTask library to sum integers in the background and update a TextView with the result.

Adding the Dependency

First, add the following dependency to your build.gradle file:

implementation 'io.github.farimarwat:asynctask:1.2'

Example: Summing Integers in the Background

Let’s create a simple example where we sum a list of integers in the background and update a TextView with the result using our custom AsyncTask.

Step 1: Layout XML

First, create a layout file activity_main.xml with a TextView and a Button:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp"
tools:context=".MainActivity">

<TextView
android:id="@+id/textViewResult"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Result"
android:textSize="18sp"
android:layout_marginBottom="16dp"/>

<Button
android:id="@+id/buttonStartTask"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Start Task"/>

</LinearLayout>

Step 2: Activity Code

Now, set up the activity to use the custom AsyncTask and bind the views using View Binding. This example demonstrates how to sum a list of integers in the background, provide progress updates, and display the result in the TextView.

package pk.farimarwat.asynctask

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import pk.farimarwat.asynctask.databinding.ActivityMainBinding
import io.github.farimarwat.asynctask.AsyncTask

class MainActivity : AppCompatActivity() {

private lateinit var binding: ActivityMainBinding

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)

binding.buttonStartTask.setOnClickListener {
val task = AsyncTask<Int, Int, Int>()
.onPreExecute {
binding.textViewResult.text = "Calculating..."
}
.doInBackground { params ->
var sum = 0
for ((index, param) in params.withIndex()) {
sum += param
publishProgress(index + 1)
}
sum
}
.onProgressUpdate { progress ->
binding.textViewResult.text = "Progress: $progress/${listOf(1, 2, 3, 4, 5).size}"
}
.onPostExecute { result ->
binding.textViewResult.text = "Result: $result"
}
.onError { throwable ->
binding.textViewResult.text = "Error: ${throwable.message}"
}

task.execute(listOf(1, 2, 3, 4, 5))
}
}
}

Understanding the Lifecycle Methods

Our custom AsyncTask provides several lifecycle methods to handle different stages of the background task:

  1. onPreExecute:
  • This method runs on the main thread before the background task starts.
  • It’s typically used to set up the UI or show a loading indicator.
  • In our example, we update the TextView to show a "Calculating..." message.

2. doInBackground:

  • This method runs on a background thread and performs the main computation.
  • It receives input parameters (provided during execute) and returns a result.
  • In our example, we sum the integers in the provided list and call publishProgress to update the progress.

3. onProgressUpdate:

  • This method runs on the main thread and updates the UI with progress information.
  • You can call publishProgress from doInBackground to trigger this method.
  • In our example, we update the TextView with the current progress.

4. onPostExecute:

  • This method runs on the main thread after the background task completes.
  • It receives the result of the background computation and updates the UI.
  • In our example, we update the TextView with the result of the sum.

5. onError:

  • This method runs on the main thread if an error occurs during the background computation.
  • In our example, we update the TextView with the error message.

Conclusion

By using the custom AsyncTask library, we've created a more modern and flexible alternative to the deprecated AsyncTask. This approach not only improves code readability but also provides better performance and error handling capabilities. We also demonstrated how to use the onProgressUpdate method to provide real-time feedback to the user.

Feel free to experiment with this custom AsyncTask class and adapt it to your specific needs. Happy coding!

--

--