I spent some time to find a developer friendly solution (without adding dependencies to the project) of how to perform some hard task in background thread and after the task is completed return result to main thread. I found "AsyncTask" which allows to do that. But to use it you need to write boilerplate code for each task you need to run in Background. I am iOS developer who decided to try Android-related developing. So in Swift you can simply use the next code to make this task:
DispatchQueue.global().async(execute: { //Do some hard task in background DispatchQueue.main.async(execute: { //Return to main }) }) This looks pretty simple. But in Kotlin I didn't find such simple solution and decided to create it.
Here is what I made:
I created Generic class
import android.os.AsyncTask class BaseAsyncTask<M>: AsyncTask<()->M, Int, M>() { var completion: ((M)->Unit)? = null override fun doInBackground(vararg params: (() -> M)?): M? { for (p in params) { return p?.invoke() } return null } override fun onPostExecute(result: M) { super.onPostExecute(result) completion?.invoke(result) } } And Manager
class AsyncManager { companion object { fun <M>execute(inBackground: ()->M, inMain: (M)->Unit): BaseAsyncTask<M> { val task = BaseAsyncTask<M>() task.completion = inMain task.execute(inBackground) return task } fun <M>execute(inBackground: ()->M): BaseAsyncTask<M> { val task = BaseAsyncTask<M>() task.execute(inBackground) return task } } } Now I use it like this:
AsyncManager.execute({ //Do some hard task in background }, { //Return to main }) Looks developer friendly.
Log.e("MAIN", "MAIN THREAD SHOULD NOT BE BLOCKED") AsyncManager.execute({ Log.e("TASK", "Started background task") val retval = "The value from background" Thread.sleep(5000) Log.e("TASK", "Finished background task with result: " + retval) retval }, { Log.e("TASK", "Started task in Main thread with result from Background: " + it) }) Log.e("MAIN", "MAIN THREAD SHOULD NOT BE BLOCKED - 1") And the log:
2019-03-27 17:11:00.719 17082-17082/com.test.testapp E/MAIN: MAIN THREAD SHOULD NOT BE BLOCKED
2019-03-27 17:11:00.722 17082-17082/com.test.testapp E/MAIN: MAIN THREAD SHOULD NOT BE BLOCKED - 1
2019-03-27 17:11:00.722 17082-17124/com.test.testapp E/TASK: Started background task
2019-03-27 17:11:05.737 17082-17124/com.test.testapp E/TASK: Finished background task with result: The value from background
2019-03-27 17:11:05.738 17082-17082/com.test.testapp E/TASK: Started task in Main thread with result from Background: The value from background
So the question is what professional Android developers think about this solution. What problem can I get in case I'll use it. And maybe there is some reason not to use this solution.