AsyncTask
应用场景:需获取子线程耗时任务的回调结果。需在Thread和Handler中编写代码逻辑,AsyncTask类将两者封装统一,相当于多线程框架
基础使用
1、以下重写的方法除doInBackground(),均在主线程中执行
2、AsyncTask的实例必须在主线程中创建,execute()必须在主线程中调用
3、一个AsyncTack的实例,只能执行一次execute方法,否则抛出异常
class MyTask extends AsyncTask<String,Object,Long>{
//泛型参数分别为传入参数类型,返回给UI线程的进度参数类型,结果参数类型
@Override protected void onPreExecute(){
super.onPreExecute();
}
@Override protected Long doInBackground(String... params){
return null;
}
@Override protected void onProgressUpdate(Object... values){
super.onProgressUpdate(values);
}
@Override protected void onPostExecute(Long s){
super.onPostExecute(s);
}
@Override protected void onCancelled(Long s){
super.onCancelled(s);
}
}
//execute(),executeOnExecutor()传入的参数对应的泛型为传入参数,因此类型要一致
//单一后台线程串行执行
new MyTask().execute(urls);
//多线程并行执行
new MyTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, urls);
//取消
AsyncTask.cancel();
AsyncTask机制的原理
本质为一个静态的线程池,任务都是提交到此线程池中执行
线程池中的工作线程执行 doInBackground(mParams)方法执行异步的任务
任务状态改变后,工作线程向UI线程发送消息,AsyncTask内部的InternalHandler响应这些消息,并调用相关的回调函数
execute:单个线程,对应线程池Executors.newSingleThreadPool
executeOnExecutor:多个线程,可自定义线程池。执行无数个,即用java线程池的Executors.newCachedThreadPool,AsyncTask默认线程池为Executors.newFixedThreadPool,最多5个。
注意事项
内存泄漏
解决方法:让内部持有外部的弱引用即可解决
生命周期
在Activity的onDestory()中及时对AsyncTask进行回收,调用其cancel()方法来保证程序的稳定性
结果丢失
当内存不足时,当前的Activity被回收,由于AsyncTask持有的是回收之前Activity的引用,导致AsyncTask更新的结果对象为一个无效的Activity的引用,这就是结果丢失
并行或串行
1.6(Donut)之前:任务串行。多个AsyncTask处理结果作用于UI视图会产生问题
1.6-3.0:任务并行。如果其中一条任务执行出现问题,会引起其他任务出现错误
3.0:顺序执行,并添加executeOnExecutor()用于并行
源码解析
//必须在UI主线程中调用该方法。
@MainThread
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
return executeOnExecutor(sDefaultExecutor, params);
}
//跳转到executeOnExecutor方法
@MainThread
public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
Params... params) {
if (mStatus != Status.PENDING) {
switch (mStatus) {
case RUNNING:
throw new IllegalStateException("Cannot execute task:"
+ " the task is already running.");
case FINISHED:
throw new IllegalStateException("Cannot execute task:"
+ " the task has already been executed "
+ "(a task can be executed only once)");
}
}
//设置当前AsyncTask的状态为RUNNING
mStatus = Status.RUNNING;
//还是在UI主线程,这个时候可以进行一些初始化操作
onPreExecute();
mWorker.mParams = params;
exec.execute(mFuture);
return this;
}
mWork变量
private final WorkerRunnable<Params, Result> mWorker;
//Callable的子类,且包含一个mParams用于保存传入的参数
private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {
Params[] mParams;
}
//mWork初始化在AsyncTask的构造函数中进行的
mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
//设置为true,下面要用到
mTaskInvoked.set(true);
Result result = null;
try {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
//获取处理结果
result = doInBackground(mParams);
Binder.flushPendingCommands();
} catch (Throwable tr) {
mCancelled.set(true);
throw tr;
} finally {
//发送执行结果
postResult(result);
}
return result;
}
};
//postResult方法
private Result postResult(Result result) {
@SuppressWarnings("unchecked")
Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
new AyncTaskResult<Result>(this, result));
//通过Hanlder发送消息
message.sendToTarget();
return result;
}
//找到相应的Hanlder
private static Handler getHandler() {
synchronized (AsyncTask.class) {
if (sHandler == null) {
sHandler = new InternalHandler();
}
return sHandler;
}
}
//消息处理
private static class InternalHandler extends Handler {
public InternalHandler() {
super(Looper.getMainLooper());
}
@SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
@Override
public void handleMessage(Message msg) {
AsyncTaskResult<?> result = (AsyncTaskResult<?>) msg.obj;
switch (msg.what) {
case MESSAGE_POST_RESULT:
result.mTask.finish(result.mData[0]);
break;
case MESSAGE_POST_PROGRESS:
result.mTask.onProgressUpdate(result.mData);
break;
}
}
}
//消息处理完之后,设定状态为finished
private void finish(Result result) {
if (isCancelled()) {
onCancelled(result);
} else {
//执行4个方法中的最后一步,处理结果
onPostExecute(result);
}
//设置最后的状态为结束finished
mStatus = Status.FINISHED;
}
mFuture变量
//申明变量
private final FutureTask<Result> mFuture;
//在AsyncTask的构造函数中进行变量的初始化
mFuture = new FutureTask<Result>(mWorker) {
@Override
protected void done() {
try {
postResultIfNotInvoked(get());
} catch (InterruptedException e) {
android.util.Log.w(LOG_TAG, e);
} catch (ExecutionException e) {
throw new RuntimeException("An error occurred while executing doInBackground()",
e.getCause());
} catch (CancellationException e) {
postResultIfNotInvoked(null);
}
}
};
//查看postResultIfNotInvoked方法,参数是get(),get()表示获取mWorker的call的返回值,即Result
private void postResultIfNotInvoked(Result result) {
//mWork初始化时设置的变量值mTaskInvoked.set(true),所以判断中一般都是wasTaskInvoked=true,所以基本不会执行
final boolean wasTaskInvoked = mTaskInvoked.get();
if (!wasTaskInvoked) {
postResult(result);
}
}
exec.execute(mFuture);
//线程池sDefaultExecutor的定义,即上述的exec
private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
//继续跟踪SERIAL_EXECUTOR
public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
//SerialExecutor的定义
private static class SerialExecutor implements Executor {
//维护一个数组队列
final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
Runnable mActive;
//执行内容
public synchronized void execute(final Runnable r) {
//在队列的尾部插入一个任务task
mTasks.offer(new Runnable() {
public void run() {
try {
r.run();
} finally {
scheduleNext();
}
}
});
if (mActive == null) {
scheduleNext();
}
}
protected synchronized void scheduleNext() {
//取出队首的任务开始执行
if ((mActive = mTasks.poll()) != null) {
//开始执行任务
THREAD_POOL_EXECUTOR.execute(mActive);
}
}
}
//THREAD_POOL_EXECUTOR
public static final Executor THREAD_POOL_EXECUTOR;
//线程池配置
static {
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS,
sPoolWorkQueue, sThreadFactory);
threadPoolExecutor.allowCoreThreadTimeOut(true);
THREAD_POOL_EXECUTOR = threadPoolExecutor;
}
//变量设置
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
// We want at least 2 threads and at most 4 threads in the core pool,
// preferring to have 1 less than the CPU count to avoid saturating
// the CPU with background work
private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4));
private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
private static final int KEEP_ALIVE_SECONDS = 30;
总结
1、在UI线程,设置当前AsyncTask的状态为RUNNING,然后执行了onPreExecute()
2、将传入的参数赋值给了mWorker.mParams。mWorker为一个Callable的子类,且在内部的call()方法中,调用了doInBackground(mParams),然后得到的返回值作为postResult的参数进行执行。postResult中通过sHandler发送消息,最终sHandler的handleMessage中完成**onPostExecute()**的调用
3、最后执行exec.execute(mFuture),mFuture为真正的执行任务的单元,将mWorker进行封装,然后由sDefaultExecutor交给线程池进行执行
onProgressUpdate()的调用时机
//使用AsyncTask中的第三个方法doInBackground时在里面我们调用了一个传递进度的方法 publishProgress(int progress)
@WorkerThread
//其实就是发送一个消息
protected final void publishProgress(Progress... values) {
if (!isCancelled()) {
//通过Handler和Message异步消息机制进行UI线程和Work线程通信
//消息类型 msg.what=MESSAGE_POST_PROGRESS
//进度 msg.obj=new AsyncTaskResult<Progress>(this, values)
getHandler().obtainMessage(MESSAGE_POST_PROGRESS,
new AsyncTaskResult<Progress>(this, values)).sendToTarget();
}
}
//处理消息
private static class InternalHandler extends Handler {
public InternalHandler() {
super(Looper.getMainLooper());
}
@SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
@Override
public void handleMessage(Message msg) {
AsyncTaskResult<?> result = (AsyncTaskResult<?>) msg.obj;
switch (msg.what) {
case MESSAGE_POST_RESULT:
result.mTask.finish(result.mData[0]);
break;
case MESSAGE_POST_PROGRESS: //处理进度消息
//调用onProgressUpdate方法显示进度
result.mTask.onProgressUpdate(result.mData);
break;
}
}
}
AsyncTask内部线程池
private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
sDefaultExecutor是SerialExecutor的一个实例,而且它是个静态变量。
一个进程里面所有AsyncTask对象都共享同一个SerialExecutor对象
深入解析AsyncTask
待更新