现在的位置: 首页 > 编程技术 > 安卓开发 > 正文

AsyncTask 的使用

2015年11月22日 安卓开发 ⁄ 共 1743字 ⁄ 字号 AsyncTask 的使用已关闭评论 ⁄ 阅读 670 次

AsyncTask是 Android 提供的在 UI 线程处理耗时操作的类,内部的实现原理是 Thread + Handle 的方式。AsyncTask 是用于处理耗时不是很长的异步操作(一般秒级的操作比较合适);如果要执行时间很长的或者循环的异步任务,推荐使用其他的多线程 API, 比如:Thread, FetureTask, ThreadPoolExecutor。

AsyncTask 是 Android 很重要的工具类,历史版本修改次数比较多,不同版本之间的区别也比较大:

Android 1.5:
AsyncTask 底层是使用唯一的线程来执行任务的,任务按顺序执行,一个执行完再执行下一个

Android 1.6:
AsyncTask 使用线程池并行执行任务,执行顺序无法保证

Android 3.0:
从 Android 3.0 开始,又改为默认按顺序执行,一个接着一个执行。但是增加了一个函数来支持多线程并发执行:AsyncTask#executeOnExecutor (Executor, Params)

下面来介绍最近的版本,Android 4.2 SDK中的:

4.2 默认是按顺序执行的,同时支持多线程并发执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
private static final int CORE_POOL_SIZE = 5; //5个核心线程
private static final int MAXIMUM_POOL_SIZE = 128; //最多分配128个线程
private static final int KEEP_ALIVE = 1; //非核心线程空闲超时1s,自动销毁
//当无空闲核心线程时,新任务添加到消息队列;消息队列填满时,再启动新的线程
private static final BlockingQueue<Runnable> sPoolWorkQueue = 
truetruetruetruetruetruenew LinkedBlockingQueue<Runnable>(10);//等待消息队列
// 并行任务执行器
public static final Executor THREAD_POOL_EXECUTOR
           = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, 
           		KEEP_ALIVE, TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);
// 顺序任务执行器
public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
// 默认使用顺序任务执行器
private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;

新添加 AsyncTask 任务时,可能出现的 4 中情况:

  1. 有空闲的核心线程时:直接使用空闲的核心线程执行异步任务
  2. 没有空闲的核心线程,但缓存队列未满时:新任务被添加到缓冲队列
  3. 没有空闲的核心线程,缓冲队列已满,但线程数没到上线时:创建新的线程执行异步任务
  4. 线程池中已满128个线程时:抛出 RejectedExecutionException

其他注意点:

  1. 由于 AsyncTask 内部的线程池是 static 类型,整个进程共用一个线程池;如果使用不当,会产生阻塞问题,尤其是单任务顺序执行的情况下,一个任务执行时间过长会阻塞其他任务的执行
  2. static 线程另外一个问题是,如果第一次调用 AsyncTask 在非 UI 线程中,那么以后使用 AsyncTask时,onPosExecute 也会在非 UI 线程中,此时如果执行 UI 操作会 Crash,所以第一次使用 AsyncTask 一定要在 UI 线程中使用,尤其是使用第三方 SDK 时要注意这点
  3. 通常使用 AsyncTask 是在 Activity 中使用匿名的内部类来使用,内部类的一个问题是会保持外部类的实例,如果 AsyncTask 中的异步任务在 Activity 退出时还没执行完或者阻塞了,那么这个保持的外部的 Activity 实例得不到释放,会引起 OOM 问,解决办法是:在 AsyncTask 使用弱引用外部实例,或者保证在 Activity 退出时,所有的 AsyncTask 已执行完成或被取消

抱歉!评论已关闭.