
在过去的十年中,AsyncTask一直是用于在Android中编写并发代码的最广泛使用的解决方案之一
但是,从 Android 11 (R) 开始,官方正式弃用, 也标志着AsyncTask 的时代正式结束
本文我们一起来回顾它的前世今生
简介
本名:AsyncTask
中文名:异步任务
出生日期:2009 年 Android 1.5 ( API Level 3 )
去世日期:2020 年 Android 11 ( API Level R )
所处位置:android.os.AsyncTask
前世
作用
AsyncTask 是安卓开发中使用的一种轻量级异步任务类。其作用是在线程池中执行后台任务,并在执行过程中将执行进度传递给主线程,当任务执行完毕后,将最终结果传递给主线程。
产生背景
安卓系统线程分为主线程和子线程,主线程也叫UI线程。主线程主要负责与用户交互。为了更好的用户体验,保证系统不因主线程的阻塞而产生卡顿,安卓系统要求主线程中不能执行耗时任务。例如:IO操作、网络请求等必须在子线程中完成。AsyncTask就是为了适应这种需要而产生。
使用方式
直接使用 AsyncTask
1 | AsyncTask.execute { |
原型
— java
1 | public abstract class AsyncTask < Params, Progress, Result > |
— kotlin
1 | abstract class AsyncTask<Params : Any!, Progress : Any!, Result : Any!> |
AsyncTask是一个泛型抽象类
参数 | 说明 |
---|---|
Params | 执行后台任务所需参数类型 |
Progress | 后台任务执行进度的类型 |
Result | 台任务执行完毕后返回结果类型 |
并非所有类型都总是由异步任务使用。要将类型标记为未使用,只需使用该类型 Void
1 | private class MyTask extends AsyncTask<Void, Void, Void> { ... } |
核心方法
AsyncTask提供4个核心方法:
protected void onPreExecute()
参数 说明 执行线程 主线程 调用时间 异步任务执行之前 方法作用 异步任务执行前的初始化工作 protected Result doInBackground(Params…params)
参数 说明 执行线程 线程池中执行 调用时间 任务开始后到任务结束之前 方法作用 用于执行异步任务 protected void onProgressUpdate(Prgress…values)
参数 说明 执行线程 主线程 调用时间 任务开始后到任务结束之前 方法作用 用于更新任务进度 protected void onPostExecute(Result result)
参数 说明 执行线程 主线程 调用时间 异步任务执行之后 方法作用 将异步任务的执行结果传递给主线程
官方示例
1 | private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> { |
DownloadFilesTask类模拟文件下载过程。传入的参数Params类型为URL(文件地址),后台任务进程参数Progress类型为Integer(下载进度),后台任务返回结果参数Result类型为Long(总文件大小)。
创建完成后,任务将非常简单地执行:
1 | new DownloadFilesTask().execute(url1, url2, url3); |
取消任务
可以通过调用cancel(boolean)随时取消任务。 调用此方法将导致对isCancelled()的后续调用返回true。 调用此方法后,在doInBackground(java.lang.Object [])返回之后,将调用onCancelled(java.lang.Object)而不是onPostExecute(java.lang.Object)。 为了确保尽快取消任务,如果可能的话(例如在循环内),应始终定期从doInBackground(java.lang.Object [])检查isCancelled()的返回值。
使用注意
- AsyncTask类必须在主线程加载
- AsyncTask对象必须在主线程创建
- execute方法必须在主线程调用
- 不要在程序中直接调用AsyncTask提供的4个核心方法
- 一个AsyncTask对象只能执行一次,即只能调用一次execute
内存泄漏
问题描述
1 | This AsyncTask class should be static or leaks might occur (anonymous android.os.AsyncTask) less... (Ctrl+F1) |
解决方法 : 静态内部类+弱引用
1 | private static class MyTask extends AsyncTask<Void, Void, String> { |
今生
abstract class AsyncTask < Params : Any!, Progress : Any!, Result : Any! >
这个类在API level R 被弃用
请使用标准的java.util.concurrent或Kotlin并发实用程序代替。
弃用原因
AsyncTask旨在启用和轻松使用UI线程。但是,最常见的用例是集成到UI中,这会导致Context泄漏,丢失的回调或配置更改崩溃。它还在平台的不同版本上具有不一致的行为,吞噬的异常doInBackground,并且不能提供比Executor直接使用更多的实用程序。
AsyncTask是为围绕Thread和Handler的帮助器类而被设计出来的,并且不构成通用的线程框架。理想情况下,应将AsyncTasks用于较短的操作(最多几秒钟)。如果需要使线程长时间运行,则强烈建议您使用java.util.concurrent包提供的各种API,例如 Executor,ThreadPoolExecutor和FutureTask。
代替示例
Executor
1 | // ----------- 示例1 ---------------------- |
ThreadPoolExecutor
1 | //核心线程池大小 --> 即需要开启多少个线程 |
FutureTask
1 | val service = Executors.newSingleThreadExecutor() |
Kotlin并发(协程)实用程序
1 | //定义耗时操作的方法 |
相关文献
- API Differences between 29 and rdp1
- AsyncTask is Deprecated, Now What?
- Deprecating AsyncTask in Android with Kotlin Coroutines
- Google depreciated AsyncTask from Android 11
以上就是本文对AsyncTask的简单回顾总结
本文发布于Android 11 / R DP 1 。如有不足,欢迎指正