前言
AsyncTask作为Android常用的异步消息机制,内部核心原理其实就是Handler。本小记不对AsyncTask基本使用作介绍,学习了AsyncTask的源码,拜读郭神文章Android AsyncTask完全解析,带你从源码的角度彻底理解. ,趁热来一发,呸,作文以记之。基于android-28。
先贴一张复习图
流程概要
开搞
1、构造方法
AsyncTask task=new AsyncTask()
写在前头
总共就三步:
- 创建Handler对象
- 创建WorkerRunnable对象
- 创建FutureTask对象
WorkerRunnable是何物,继承于Callable,内置call方法,浅尝辄止~
FutureTask是何物,继承于Runnable,内置run方法,且引用了WorkerRunnable对象,什么作用暂且不谈,先mark~
public AsyncTask(@Nullable Looper callbackLooper) {
mHandler = callbackLooper == null || callbackLooper == Looper.getMainLooper()
? getMainHandler()
: new Handler(callbackLooper);
mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
mTaskInvoked.set(true);
Result result = null;
try {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
//noinspection unchecked
result = doInBackground(mParams);
Binder.flushPendingCommands();
} catch (Throwable tr) {
mCancelled.set(true);
throw tr;
} finally {
postResult(result);
}
return result;
}
};
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);
}
}
};
}
2、执行
task.execute(params);
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
return executeOnExecutor(sDefaultExecutor, params);
}
默认执行方法的本质是调用了
executeOnExecutor(Executor exec, Params... params)//其第一个参数为线程池对象
不看源码,先总结executeOnExecutor核心步骤
- 执行onPreExecute(),也就很好地说明了onPreExecute在任务启动前执行
- 赋值params给WorkerRunnable对象,也就相当于丢到了FutureTask里(因为他们有PY交易关系)
-
线程池启动FutureTask
这里有两个重点,线程池对象和FutureTask对象,源码里sDefaultExecutor是默认的线程池对象
public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
然后贴出executeOnExecutor部分代码
@MainThread
public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
Params... params) {
...ignore...
onPreExecute();
mWorker.mParams = params;
exec.execute(mFuture);
return this;
}
3、默认线程池sDefaultExecutor
sDefaultExecutor是静态内部类SerialExecutor的一个实例,不看源码直接总结其execute方法
- 将任务加入队列->offer
-
出列任务->poll,如果还有任务,则让另一个小弟来执行任务->THREAD_POOL_EXECUTOR.execute
说白了sDefaultExecutor它就是个甩锅的,棵棵
private static class SerialExecutor implements Executor {
final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
Runnable mActive;
public synchronized void execute(final Runnable r) {
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也是线程池对象,暂不深究,反正接下来的动作是执行于子线程中,啊 仿佛闻到了doInBackground的香气。最终要执行FutureTask.run,来了,FutureTask终于来了
4、FutureTask&WorkerRunnable
直接干核心run方法,其实里面就主要是callable.call(),callable对象哪里来,当然是那位有点♂哲学关系的WorkerRunnable兄弟,直接进入WorkerRunnable.call()一看究竟
FutureTask.run部分代码,c即callable实例
public void run() {
...ignore...
try {
result = c.call();
ran = true;
} catch (Throwable ex) {
result = null;
ran = false;
setException(ex);
}
} finally {
...ignore...
}
}
上面创建AsyncTask构造方法时,也创建了WorkerRunnable。
先给call方法作个总结:
- 设置线程优先级
- 执行doInBackground
- 结束后执行postResult
mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
mTaskInvoked.set(true);
Result result = null;
try {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
//noinspection unchecked
result = doInBackground(mParams);
Binder.flushPendingCommands();
} catch (Throwable tr) {
mCancelled.set(true);
throw tr;
} finally {
postResult(result);
}
return result;
}
};
其中doInBackground就是我们很熟悉的,需要重写的抽象函数
进入postResult(result),发现了handler的踪迹
private Result postResult(Result result) {
@SuppressWarnings("unchecked")
Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
new AsyncTaskResult<Result>(this, result));
message.sendToTarget();
return result;
}
进入getHandler,层层上翻,发现这里的handler对象是InternalHandler是示例
private static Handler getMainHandler() {
synchronized (AsyncTask.class) {
if (sHandler == null) {
sHandler = new InternalHandler(Looper.getMainLooper());
}
return sHandler;
}
}
且看InternalHandler
public void handleMessage(Message msg) {
AsyncTaskResult<?> result = (AsyncTaskResult<?>) msg.obj;
switch (msg.what) {
case MESSAGE_POST_RESULT:
// There is only one result
result.mTask.finish(result.mData[0]);
break;
case MESSAGE_POST_PROGRESS:
result.mTask.onProgressUpdate(result.mData);
break;
}
}
handleMessage里有两个what,一个是MESSAGE_POST_RESULT即上面postResult发送的,进入.mTask.finish,任务终于收网了,若中途被取消则执行onCancelled(result),否则执行熟悉的 onPostExecute(result)
private void finish(Result result) {
if (isCancelled()) {
onCancelled(result);
} else {
onPostExecute(result);
}
mStatus = Status.FINISHED;
}
handleMessage的空一格what,MESSAGE_POST_PROGRESS很显然是更新进度,调用熟悉的onProgressUpdate,在哪里发送呢?必须是publishProgress
protected final void publishProgress(Progress... values) {
if (!isCancelled()) {
getHandler().obtainMessage(MESSAGE_POST_PROGRESS,
new AsyncTaskResult<Progress>(this, values)).sendToTarget();
}
}
补充
任务调度的默认线程池是SerialExecutor
public synchronized void execute(final Runnable r) {
mTasks.offer(new Runnable() {
public void run() {
try {
r.run();
} finally {
scheduleNext();
}
}
});
if (mActive == null) {
scheduleNext();
}
}
分析其代码,执行完一个任务后,在finally进行下一个任务的检查,当有多个任务
new MyAsyncTask("AsyncTask#1").execute("");
new MyAsyncTask("AsyncTask#2").execute("");
new MyAsyncTask("AsyncTask#3").execute("");
new MyAsyncTask("AsyncTask#4").execute("");
new MyAsyncTask("AsyncTask#5").execute("");
那么
AsyncTask是默认串行工作的(依次排队挨打)
如果不需要考虑并发带来的问题,可以
自定义线程池对象,调用executeOnExecutor达到并行效果(一排同时挨打)
网友评论