AsyncTask
作為Android原生的一個異步加載類蔼紧,在前幾年還是非常流行的仙辟,但隨著RxJava和RxAndroid的流行境蜕,它的吸引力降低了不少撑教。AsyncTask
是通過對Thread
和Handler
的封裝叹话,簡化我們的操作偷遗,滿足我們在線程里面進行計算,在主線程更新UI驼壶。但是AsyncTask
適用于短時操作(最多幾秒鐘)氏豌,并不推薦用于長時間的耗時操作(現(xiàn)在版本的AsyncTask
任務(wù)的執(zhí)行是串行,當然也可以自己選并行)热凹。
AsyncTask
的使用還是非常簡單的泵喘,下面就是使用的例子:
public class MyAsyncTask extends AsyncTask<String, Integer, String> {
/**
* 運行異步線程的任務(wù)
* @param strings
* @return
*/
@Override
protected String doInBackground(String... strings) {
return null;
}
/**
* 運行在主線程,接受異步線程任務(wù)的結(jié)果
* @param s
*/
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
}
/**
* 運行在主線程般妙,在異步線程執(zhí)行前執(zhí)行纪铺,可以做一些準備工作
*/
@Override
protected void onPreExecute() {
super.onPreExecute();
}
/**
*
* 運行在主線程,加載進度
* @param values
*/
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
}
/**
* 運行在主線程碟渺,取消監(jiān)聽
*/
@Override
protected void onCancelled() {
super.onCancelled();
}
}
new MyAsyncTask().execute("執(zhí)行");
使用起來就是如此的簡單爽快鲜锚。
AsyncTask
的源碼分析:
public abstract class AsyncTask<Params, Progress, Result> {
private static final String LOG_TAG = "AsyncTask";
//CPU數(shù)量
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
//線程池核心線程數(shù)量,最多4個苫拍,最少2個
private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4));
//線程池最大線程數(shù)量
private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
//空閑線程的存活時間30s
private static final int KEEP_ALIVE_SECONDS = 30;
//線程池創(chuàng)建線程的線程工廠
private static final ThreadFactory sThreadFactory = new ThreadFactory() {
//使用原子整數(shù)烹棉,可以保證在超高并發(fā)下工作
private final AtomicInteger mCount = new AtomicInteger(1);
public Thread newThread(Runnable r) {
return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());
}
};
//靜態(tài)阻塞式隊列,用來存放待執(zhí)行的任務(wù)怯疤,初始容量為128
//這個阻塞式隊列很特別類浆洗,主要提供了兩個方法put()和take(),
// 前者將一個對象放到隊列中集峦,如果隊列已經(jīng)滿了伏社,就等待直到有空閑節(jié)點抠刺;
// 后者從head取一個對象,如果沒有對象摘昌,就等待直到有可取的對象
private static final BlockingQueue<Runnable> sPoolWorkQueue =
new LinkedBlockingQueue<Runnable>(128);
//靜態(tài)并行執(zhí)行器速妖,3.0以前這是AsyncTask的默認執(zhí)行器
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;
}
//靜態(tài)串行執(zhí)行器,內(nèi)部進行了串行控制聪黎,可以不斷的遞歸任務(wù)執(zhí)行
public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
//Handler的消息類型罕容,發(fā)送結(jié)果
private static final int MESSAGE_POST_RESULT = 0x1;
//Handler的消息類型,發(fā)送進度
private static final int MESSAGE_POST_PROGRESS = 0x2;
//默認執(zhí)行器稿饰,從3.0開始锦秒,默認使用串行
private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
//靜態(tài)Handler,使用懶加載方式,使用時才創(chuàng)建喉镰,而且使用了單例模式
private static InternalHandler sHandler;
//任務(wù)執(zhí)行相關(guān)的兩個類
private final WorkerRunnable<Params, Result> mWorker;
private final FutureTask<Result> mFuture;
//當前狀態(tài)旅择,默認是未執(zhí)行狀態(tài)
private volatile android.os.AsyncTask.Status mStatus = android.os.AsyncTask.Status.PENDING;
//是否取消
private final AtomicBoolean mCancelled = new AtomicBoolean();
//任務(wù)是否被執(zhí)行
private final AtomicBoolean mTaskInvoked = new AtomicBoolean();
//用于執(zhí)行消息發(fā)送的Handler, 默認是把sHandler賦值給他
private final Handler mHandler;
//靜態(tài)串行執(zhí)行器類
private static class SerialExecutor implements Executor {
//一個既可以用于隊列又可以用于棧的類,它的執(zhí)行速度比LinkList和Stack快侣姆;
//這個是用于隊列
final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
//當前正在執(zhí)行的任務(wù)
Runnable mActive;
public synchronized void execute(final Runnable r) {
mTasks.offer(new Runnable() {
public void run() {
//下面這段代碼保證了串行的執(zhí)行機制生真,使用try{}finally{}模式,也是十分有想象力的
try {
r.run();
} finally {
scheduleNext();
}
}
});
if (mActive == null) {
scheduleNext();
}
}
protected synchronized void scheduleNext() {
if ((mActive = mTasks.poll()) != null) {
THREAD_POOL_EXECUTOR.execute(mActive);
}
}
}
public enum Status {
// 當前還未執(zhí)行任務(wù)捺宗,正在等待任務(wù)加入
PENDING,
// 當前正在執(zhí)行任務(wù)
RUNNING,
//任務(wù)執(zhí)行完成(標志onPostExecute完成)
FINISHED,
}
private static Handler getMainHandler() {
synchronized (android.os.AsyncTask.class) {
if (sHandler == null) {
//保證了Hanlder的執(zhí)行是在主線程
sHandler = new InternalHandler(Looper.getMainLooper());
}
return sHandler;
}
}
private Handler getHandler() {
return mHandler;
}
//可以用于切換執(zhí)行器柱蟀,使用并行方式,這方法被隱藏了蚜厉,官方希望我們使用默認方式
public static void setDefaultExecutor(Executor exec) {
sDefaultExecutor = exec;
}
public AsyncTask() {
this((Looper) null);
}
public AsyncTask(@Nullable Handler handler) {
this(handler != null ? handler.getLooper() : null);
}
public AsyncTask(@Nullable Looper callbackLooper) {
//以前AsyncTask要求初始化一定要放在主線程长已,現(xiàn)在沒這個要求了
mHandler = callbackLooper == null || callbackLooper == Looper.getMainLooper()
? getMainHandler()
: new Handler(callbackLooper);
mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
//設(shè)置正在執(zhí)行任務(wù)
mTaskInvoked.set(true);
Result result = null;
try {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
//這里異步任務(wù)被執(zhí)行,返回結(jié)果
result = doInBackground(mParams);
Binder.flushPendingCommands();
} catch (Throwable tr) {
mCancelled.set(true);
throw tr;
} finally {
//結(jié)果返回
postResult(result);
}
return result;
}
};
mFuture = new FutureTask<Result>(mWorker) {
//mWorker的Call()執(zhí)行完后弯囊,再執(zhí)行,這里主要處理異常情況痰哨,如被取消
@Override
protected void done() {
try {
//get()方法是一個阻塞方法,直到mWorker的Call()執(zhí)行有結(jié)果后才會執(zhí)行
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);
}
}
};
}
//發(fā)布結(jié)果
private void postResultIfNotInvoked(Result result) {
final boolean wasTaskInvoked = mTaskInvoked.get();
if (!wasTaskInvoked) {//正常情況下匾嘱,wasTaskInvoked為true
postResult(result);
}
}
//Handler發(fā)送結(jié)果消息
private Result postResult(Result result) {
@SuppressWarnings("unchecked")
Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
new AsyncTaskResult<Result>(this, result));
message.sendToTarget();
return result;
}
public final android.os.AsyncTask.Status getStatus() {
return mStatus;
}
//執(zhí)行在線程里面斤斧,用于需要重寫
@WorkerThread
protected abstract Result doInBackground(Params... params);
//執(zhí)行在主線程,運行在doInBackground前面霎烙,可以做一些準備工作撬讽,如進度條的初始化
@MainThread
protected void onPreExecute() {
}
//執(zhí)行在主線程,子線程處理得到的結(jié)果
@SuppressWarnings({"UnusedDeclaration"})
@MainThread
protected void onPostExecute(Result result) {
}
//執(zhí)行在主線程悬垃,處理進度
@SuppressWarnings({"UnusedDeclaration"})
@MainThread
protected void onProgressUpdate(Progress... values) {
}
//執(zhí)行在主線程游昼,任務(wù)取消,這個方法尝蠕,用戶不應(yīng)該自己調(diào)用
@SuppressWarnings({"UnusedParameters"})
@MainThread
protected void onCancelled(Result result) {
onCancelled();
}
//執(zhí)行在主線程烘豌,任務(wù)取消
@MainThread
protected void onCancelled() {
}
//任務(wù)是否被取消
public final boolean isCancelled() {
return mCancelled.get();
}
//取消任務(wù)
public final boolean cancel(boolean mayInterruptIfRunning) {
mCancelled.set(true);
return mFuture.cancel(mayInterruptIfRunning);
}
public final Result get() throws InterruptedException, ExecutionException {
return mFuture.get();
}
public final Result get(long timeout, TimeUnit unit) throws InterruptedException,
ExecutionException, TimeoutException {
return mFuture.get(timeout, unit);
}
//任務(wù)執(zhí)行
@MainThread
public final android.os.AsyncTask<Params, Progress, Result> execute(Params... params) {
return executeOnExecutor(sDefaultExecutor, params);
}
@MainThread
public final android.os.AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
Params... params) {
if (mStatus != android.os.AsyncTask.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 = android.os.AsyncTask.Status.RUNNING;
//看這里,果然是先執(zhí)行
onPreExecute();
mWorker.mParams = params;
exec.execute(mFuture);
return this;
}
//還可以直接執(zhí)行Runnable
@MainThread
public static void execute(Runnable runnable) {
sDefaultExecutor.execute(runnable);
}
@WorkerThread
protected final void publishProgress(Progress... values) {
if (!isCancelled()) {
getHandler().obtainMessage(MESSAGE_POST_PROGRESS,
new AsyncTaskResult<Progress>(this, values)).sendToTarget();
}
}
private void finish(Result result) {
if (isCancelled()) {
onCancelled(result);//如果取消了看彼,走取消監(jiān)聽
} else {
onPostExecute(result);//否則廊佩,發(fā)布計算結(jié)果
}
//從這里可以看出囚聚,onCancelled和onPostExecute是互斥的
mStatus = android.os.AsyncTask.Status.FINISHED;
}
private static class InternalHandler extends Handler {
public InternalHandler(Looper looper) {
super(looper);
}
@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;
}
}
}
private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {
Params[] mParams;
}
@SuppressWarnings({"RawUseOfParameterizedType"})
private static class AsyncTaskResult<Data> {
final android.os.AsyncTask mTask;
final Data[] mData;
AsyncTaskResult(android.os.AsyncTask task, Data... data) {
mTask = task;
mData = data;
}
}
}
總結(jié):
1、AsyncTask
其實只是對Thread和Handler進行了一些封裝标锄;
2顽铸、AsyncTask
默認使用的是串行的執(zhí)行方式,這就要求我們不要去執(zhí)行太耗時的任務(wù)料皇,官方告訴我們執(zhí)行時間最好是幾秒谓松;
3、我們可以手動將AsyncTask
的執(zhí)行方式改為并行執(zhí)行践剂,方法是executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, Params... params)