前言:AsyncTask 负责在 Android 中执行异步任务,它允许我们以非线程阻塞的方式执行操作。但是在 API 30,AsyncTask 被 Android 标记为 Deprecated。
官方文档:
https://developer.android.google.cn/reference/android/os/AsyncTask
官方给出的解决方案是:
Use the standard java.util.concurrent
or Kotlin concurrency utilities
instead.
一、什么是 AsyncTask?
在Java中,AsyncTask 实现如下所示:
class SampleAsyncTask extends AsyncTask {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Void doInBackground(Void... voids) {
return null;
}
@Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
}
}
执行AsyncTask
的execute
,首先触发onPreExecute
回调,然后交给线程池sDefaultExecutor
调度,mFuture
配合mWorker
开启子线程,触发doInBackground
回调,然后交给内部单例InternalHandler
处理返回结果并返回到主线程,最后根据Message
处理onProgressUpdate
或onPostExecute
。
关于 AsyncTask 源码解析可以看我写的另一篇文章:
【Android】深入解析 AsyncTask 源码
二、为什么 AsyncTask 在 Android 中被废弃?
在 Android 中的AsyncTask
有太多问题,例如:由于AsyncTask
与Activity
或Fragment
的生命周期无关而导致的内存泄漏等等。
如果你对执行AsyncTask
使用不当,最终会在意想不到的地方发生崩溃。这对于用户和开发人员来说都不是好事。
官方文档给出我们两种替代方案:
- Java 代码:
Executor
或ThreadPoolExecutor
或FutureTask
- Kotlin 代码:
Kotlin 协程
三、针对 Java 代码,使用 Executors 替代
Executors 是一种结构化的服务,可以管理多个线程(池)。 可以指定要在内存中保留多少个线程。 如果提供的线程池数量超出可接受的数量,它们将被保留在队列中。
注:确保仅创建一个ExecutorService
实例。
示例代码:
public class TestActivity extends AppCompatActivity {
private ExecutorService executorService;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
executorService = Executors.newFixedThreadPool(1);
doAsyncCode();
}
private void doAsyncCode() {
executorService.submit(new Runnable() {
@Override
public void run() {
// 执行你的耗时操作代码
...
doOnUiCode();
}
});
}
private void doOnUiCode() {
Handler uiThread = new Handler(Looper.getMainLooper());
uiThread.post(new Runnable() {
@Override
public void run() {
// 更新你的UI
}
});
}
@Override
protected void onStop() {
super.onStop();
if (!executorService.isShutdown()) {
executorService.shutdownNow();
}
}
}
四、针对 Kotlin 代码,使用 Kotlin coroutines 替代
导入协程库:
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.9'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9'
示例代码:
class MainActivity : AppCompatActivity() {
val errorHandler = CoroutineExceptionHandler { coroutineContext, throwable ->
// 发生异常时的捕获
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
GlobalScope.launch(errorHandler) {
withContext(Dispatchers.IO) {
// 执行你的耗时操作代码
...
doOnUiCode()
}
}
}
private suspend fun doOnUiCode() {
withContext(Dispatchers.Main) {
// 更新你的UI
}
}
}
© 2020 Tyhoo Wu, All rights reserved.