Last time I showed how to execute an AsyncTask in Jquery style. Now I will show how to do it in Kotlin.
Kotlin has much better support for functional programming, functions/lambdas are first class member of the language. A parameter of a method can be just typed function rather than having to be interface. So I don’t have to create interface for Func<T> and Action<T>.
This is how MyAsyncTask<T> looks like in Kotlin, note the type of task and completionHandler are ()->T or (T)->Unit?.
class MyAsyncTask<T>(private val task: () -> T) : AsyncTask<Void, Void, T>() {
private var completionHandler: ((T) -> Unit)? = null
private var errorHandler: ((Exception) -> Unit)? = null
private var exception: Exception? = null
fun setCompletionHandler(action: (T) -> Unit) {
this.completionHandler = action
}
fun setErrorHandler(action: (Exception) -> Unit) {
this.errorHandler = action
}
override fun doInBackground(vararg voids: Void): T? {
try {
return task.invoke()
} catch (ex: Exception) {
exception = ex
}
return null
}
override fun onPostExecute(result: T) {
if (exception != null && errorHandler != null) {
errorHandler!!.invoke(exception!!)
} else if (completionHandler != null) {
completionHandler!!.invoke(result)
}
}
}
And here is Async<T>:
class Async<T> private constructor() {
private var task: MyAsyncTask<T>? = null
fun whenComplete(action: (T) -> Unit): Async<T> {
task!!.setCompletionHandler(action)
return this
}
fun onError(action: (Exception) -> Unit): Async<T> {
task!!.setErrorHandler(action)
return this
}
fun execute() {
try {
task!!.execute()
} catch (ex: Exception) {
ex.printStackTrace()
}
}
companion object {
fun <T> run(task: () -> T): Async<T> {
val runner = Async<T>()
runner.task = MyAsyncTask(task)
return runner
}
}
}
Here is an example of how it is used.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Async.run {
val api = MyAPI()
api.signInUser("user_name", "password")
}.whenComplete {
//it.displayName
}.onError {
//it.message
}.execute()
}