【发布时间】:2019-08-18 05:39:33
【问题描述】:
我花了一些时间寻找一个开发人员友好的解决方案(不向项目添加依赖项)如何在后台线程中执行一些硬任务,并在任务完成后将结果返回到主线程。我找到了允许这样做的“AsyncTask”。但是要使用它,您需要为需要在后台运行的每个任务编写样板代码。我是 iOS 开发者,决定尝试 Android 相关的开发。所以在 Swift 中你可以简单地使用下面的代码来完成这个任务:
DispatchQueue.global().async(execute: {
//Do some hard task in background
DispatchQueue.main.async(execute: {
//Return to main
})
})
这看起来很简单。但是在 Kotlin 中我没有找到这么简单的解决方案,于是决定创建它。
这是我做的:
我创建了通用类
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)
}
}
和经理
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
}
}
}
现在我这样使用它:
AsyncManager.execute({
//Do some hard task in background
}, {
//Return to main
})
看起来对开发者友好。
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")
还有日志:
2019-03-27 17:11:00.719 17082-17082/com.test.testapp E/MAIN: MAIN 线程不应该被阻塞
2019-03-27 17:11:00.722 17082-17082/com.test.testapp E/MAIN: MAIN 线程不应该被阻塞 - 1
2019-03-27 17:11:00.722 17082-17124/com.test.testapp E/TASK: 开始 后台任务
2019-03-27 17:11:05.737 17082-17124/com.test.testapp E/TASK: 完成 具有结果的后台任务:来自后台的值
2019-03-27 17:11:05.738 17082-17082/com.test.testapp E/TASK: 开始 主线程中的任务,结果来自背景:值来自 背景
所以问题是专业的 Android 开发人员如何看待这个解决方案。如果我会使用它,我会遇到什么问题。也许有一些理由不使用这个解决方案。
【问题讨论】:
标签: android multithreading kotlin android-asynctask