-----基于Android6.0分析
AsyncTask是一個(gè)抽象類,我們?nèi)ナ褂盟臅r(shí)候需要?jiǎng)?chuàng)建一個(gè)子類繼承它。
它是Android為我們封裝的處理耗時(shí)操作的類
AsyncTask也是使用的異步消息處理機(jī)制,只是做了非常好的封裝而已。
framework/base/core/java/android/os/AsyncTask.java
public abstract class AsyncTask<Params, Progress, Result>
AsyncTask的參數(shù)由三個(gè)泛型設(shè)定,所以當(dāng)我們創(chuàng)建子類的時(shí)候必須為其制定泛型的類型,下面由一個(gè)例子來(lái)說(shuō)明,這三個(gè)泛型會(huì)影響AsyncTask類中的哪幾個(gè)函數(shù)的參數(shù)和返回值
import android.os.AsyncTask;
public class DownLoadTask extends AsyncTask<String, Void, Boolean>{
@Override
protected Boolean doInBackground(String... params) {
// TODO Auto-generated method stub
return null;
}
@Override
protected void onPostExecute(Boolean result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
}
@Override
protected void onProgressUpdate(Void... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
}
}
Params:doInBackground的參數(shù)類型
Progress:onProgressUpdate的參數(shù)類型
Result:doInBackground的返回類型和onPostExecute參數(shù)類型

我們首先來(lái)看下AsyncTask的構(gòu)造函數(shù),初始化兩個(gè)參數(shù)mWorker 和mFuture,mWorker是一個(gè)Callable對(duì)象,mFuture是一個(gè)FutureTask對(duì)象
public AsyncTask() {
mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
mTaskInvoked.set(true);
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
//noinspection unchecked
Result result = doInBackground(mParams);
Binder.flushPendingCommands();
return postResult(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);
}
}
};
}
private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {
Params[] mParams;
}
FutureTask 這個(gè)類在我們電腦上配置的JAVA環(huán)境中的 rt.jar 中
// packname:java.util.concurrent
public FutureTask(Callable<V> paramCallable)
{
if (paramCallable == null)
throw new NullPointerException();
this.callable = paramCallable;
this.state = 0;
}
把mWorker 保存在FutureTask 的callable 變量中。到這里,AsyncTask的初始化工作已經(jīng)完成。下面就是Task的啟動(dòng)execute方法
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
return executeOnExecutor(sDefaultExecutor, params);
}
// private static volatile Executor sDefaultExecutor = new SerialExecutor();
接著看 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)");
}
}
mStatus = Status.RUNNING;
onPreExecute();
mWorker.mParams = params;
exec.execute(mFuture);
return this;
}
函數(shù)中 首先會(huì)執(zhí)行onPreExecute(),可是doInBackground()是哪調(diào)用的呢,不用著急,我們慢慢找找,唯一可疑的就是exec.execute(mFuture);這個(gè)方法,我們點(diǎn)進(jìn)去看看。因?yàn)閑xec就是剛才傳進(jìn)去的sDefaultExecutor,而sDefaultExecutor又是SerialExecutor對(duì)象,所以這里調(diào)用的就是SerialExecutor的execute方法。
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);
}
}
}
仔細(xì)觀察上面的代碼,設(shè)計(jì)的很有意思,
public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
SerialExecutor在AsyncTask以常量的形式被使用,因此整個(gè)應(yīng)用程序中的所有AsyncTask實(shí)例都會(huì)共用同一個(gè)SerialExecutor。SerialExecutor采用ArrayDeque這個(gè)隊(duì)列來(lái)維護(hù)添加進(jìn)的線程任務(wù)Runable.當(dāng)我們一次性執(zhí)行很多任務(wù)時(shí),第一次運(yùn)行會(huì)mActive 肯定等于null了,所以就調(diào)用scheduleNext函數(shù),
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
private static final int CORE_POOL_SIZE = CPU_COUNT + 1;
private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
public static final Executor THREAD_POOL_EXECUTOR
= new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,
TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);
允許在同一時(shí)刻有CORE_POOL_SIZE個(gè)任務(wù)正在執(zhí)行,并且最多能夠存儲(chǔ)MAXIMUM_POOL_SIZE個(gè)任務(wù)。
他會(huì)取出ArrayDeque的隊(duì)首的Runable給mActive ,然后執(zhí)行 THREAD_POOL_EXECUTOR.execute(mActive);去啟動(dòng)Runable的Run函數(shù),之后又有新的任務(wù)被offer到隊(duì)列中,這次mActive已然不等null,因?yàn)樗4媪说谝淮蔚奶砑舆M(jìn)來(lái)的Runable對(duì)象。但是呢,在run函數(shù)中有這么一段代碼
try {
r.run();
} finally {
scheduleNext();
}
每次執(zhí)行完Runable的任務(wù)后,都會(huì)去執(zhí)行scheduleNext()函數(shù),這就保證同一時(shí)刻只會(huì)有一個(gè)線程正在執(zhí)行,其余的均處于等待狀態(tài),是不是有點(diǎn)像單一線程池的效果。接下來(lái),可以知道execute開辟了一個(gè)線程Runnable 去執(zhí)行mFuture的run函數(shù)
public void run()
{
.......
try
{
Callable localCallable = this.callable;
if ((localCallable != null) && (this.state == 0))
{
Object localObject1;
int j;
try
{
localObject1 = localCallable.call();
j = 1;
}
catch (Throwable localThrowable)
{
......
}
if (j != 0)
set(localObject1);
}
}
......
}
this.callable就是AsyncTask初始化創(chuàng)建的mWorker即WorkerRunnable對(duì)象,這里主要是調(diào)用了其call()函數(shù),再來(lái)看看WorkerRunnable的call函數(shù)到底做了哪些工作
mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
mTaskInvoked.set(true);
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
//noinspection unchecked
Result result = doInBackground(mParams);
Binder.flushPendingCommands();
return postResult(result);
}
};
這是AsyncTask構(gòu)造函數(shù)中的一段代碼,發(fā)現(xiàn)了沒有,里面執(zhí)行了doInBackground函數(shù)。到現(xiàn)在 我們把思路捋一下。
1、初始化AsyncTask的時(shí)候會(huì)創(chuàng)建mWorker和mFuture對(duì)象,在mFuture中會(huì)把mWorker當(dāng)做參數(shù)傳給mFuture的callable成員變量
2、執(zhí)行exec的時(shí)候會(huì)調(diào)用executeOnExecutor,然后在executeOnExecutor里面調(diào)用onPreExecute,exec.execute(mFuture);
3、SerialExecutor是AsyncTask的內(nèi)部靜態(tài)類。exec.execute(mFuture)會(huì)調(diào)用SerialExecutor的execute函數(shù),在這里面會(huì)開辟線程去執(zhí)行mFuture.run(),緊接著run函數(shù)調(diào)用mWorker的call函數(shù),進(jìn)而執(zhí)行doInBackground,經(jīng)過這幾步,不難doInBackground執(zhí)行在子縣城中,這就是為什么doInBackground可以執(zhí)行耗時(shí)操作的原因。
緊接著我們看postResult的源碼
private Result postResult(Result result) {
@SuppressWarnings("unchecked")
Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
new AsyncTaskResult<Result>(this, result));
message.sendToTarget();
return result;
}
熟悉android Handler機(jī)制的同學(xué)應(yīng)該會(huì)知道,這條消息最終會(huì)被getHandler()得到的Handler對(duì)象中handleMessage去處理
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:
// There is only one result
result.mTask.finish(result.mData[0]);
break;
case MESSAGE_POST_PROGRESS:
result.mTask.onProgressUpdate(result.mData);
break;
}
}
}
handleMessage中的消息有兩個(gè)類型
1.MESSAGE_POST_RESULT
private void finish(Result result) {
if (isCancelled()) {
onCancelled(result);
} else {
onPostExecute(result);
}
mStatus = Status.FINISHED;
}
如果task沒有取消就調(diào)用onPostExecute,取消的話就執(zhí)行onCancelled
2.MESSAGE_POST_PROGRESS
protected final void publishProgress(Progress... values) {
if (!isCancelled()) {
sHandler.obtainMessage(MESSAGE_POST_PROGRESS,
new AsyncTaskResult<Progress>(this, values)).sendToTarget();
}
}
這也說(shuō)明在doInBackground中調(diào)用publishProgress可以總子線程切換到UI線程從而進(jìn)行UI線程的控件更新。
好了,AsyncTask的原理到這里就介紹完了。