AsyncTask is deprecated, now what? — Part 2

Idan Damri
3 min readOct 9, 2020

--

So for those of you that followed me, I showed you a way to replace AsyncTask with Runnables in Java. At the end of the article, I suggested a to work with Rx java or coroutines before working with the solution I showed, which was kind of a band-aid solution because of demands at that time. Now I am going to give you the way to handle the same process of replacing AsyncTask with coroutines.

For the sake of understanding, I am going to use the same example a snippet from the last article I wrote that is the AsyncTask I want to replace:

public class myAsyncTask extends AsyncTask<Void, Void, String> {

WeakReference<myInteface> myIntefaceWeakReference;

public myAsyncTask(myInteface listener) {
this.myIntefaceWeakReference = new WeakReference<>(listener);
}

@Override
protected void onPreExecute() {
if(myIntefaceWeakReference != null && myIntefaceWeakReference.get() != null){
myIntefaceWeakReference.get().doWorkBeforeBackground();
}
}

@Override
protected String doInBackground(Void... voids) {
String result = someNetworkFunction();
return result;
}

@Override
protected void onPostExecute(Object s) {
if(myIntefaceWeakReference != null && myIntefaceWeakReference.get() != null){
myIntefaceWeakReference.get().doWorkAfterBackground((String)s);
}
}
}
interface myInteface {
void doWorkBeforeBackground();
void doWorkAfterBackground(Object result);
}

In order to start, we need to import coroutines through Gradle. Let’s add the dependency inside the apps build.gradle :
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9'

Let’s start:

doWorkBeforeBackground()   // on Ui thread
CoroutineScope(Dispatchers.IO).launch {
try {
val api = someNetworkFunction()
withContext(Dispatchers.Main) {
try {
doWorkAfterBackground(api.data);
} catch (e: Exception) {
e.printStackTrace()
}
}
} catch (e: Exception) {
e.printStackTrace()
}
}

So basically the call for “doWorkBeforeBackground()” is being done on the UI thread and being called in the same manner as “onPreExecute” would of being called.(Of course, this part is not a must process like in AsyncTask that onPreExecute doesn’t need to be overridden)

Now let’s talk about the interesting part which is the Coroutine. As you can see we use something called “CoroutineScope” (Note that all coroutines must run in a scope). The “launch” is a function that creates a coroutine and dispatches the execution of its function body to the corresponding dispatcher.
Dispatchers.IO” indicates that this coroutine should be executed on a thread reserved for I/O operations (it resembles the thread that handles the “doInBackground” operation).

As you can see I called the “someNetworkFunction()” on the scope of the “Dispatchers.IO” that is not the UI thread, by doing so the UI thread won’t be stuck.

When the result is gotten we proceed to “withContext(Dispatchers.Main)” which is in a way the equivalent of the “onPostExecute” part of the AsyncTask.

You can see that for this part the selected dispatcher is the “Main” and not “IO” which means we are returning to the UI thread.

So as you can see there is a lot less code, less room for error and bugs, as well as really readable.

Of course that when using the replacement I think this is the most perfect solution for some reasons:

1) As mentioned it has less code which means fewer bugs to be created.

2) This solution is Kotlin based and not Java-based.

3) This solution is a lot understandable and readable.

Hope this seems like a better understanding of the coroutines process.

If you want me to release a new article about an RxJava solution write in the comments and I will create one.

--

--

Idan Damri

Enthusiastic Android developer, as GEEK as they get..