<p>AsyncTask enables proper and easy use of the UI thread. This class allows you
* to perform background operations and publish results on the UI thread without
* having to manipulate threads and/or handlers.</p>複製代碼
inner class TestAsyncTask : AsyncTask<Int, Int, String>() {
override fun doInBackground(vararg params: Int?): String {
Log.e("method:", "doInBackground()")
Log.e("Thread:", Thread.currentThread().name)
val stringBuilder = StringBuilder()
for (i in params[0]!!..params[0]!! + 10) { // 輸出信息
stringBuilder.append(i)
publishProgress(i) // 更新當前進度
Thread.sleep(500)
}
return stringBuilder.toString()
}
override fun onPreExecute() {
super.onPreExecute()
Log.e("method:", "onPreExecute()")
Log.e("Thread:", Thread.currentThread().name)
}
override fun onProgressUpdate(vararg i: Int?) {
super.onProgressUpdate(*i)
Log.e("method:", "onProgressUpdate()")
Log.e("Thread:", Thread.currentThread().name)
Log.e("Progress:", i.toString())
}
override fun onPostExecute(result: String?) {
super.onPostExecute(result)
Log.e("method:", "onPostExecute()")
Log.e("Thread:", Thread.currentThread().name)
}
}複製代碼
TestAsyncTask().execute(0)複製代碼
相信對於AsyncTask 的使用沒什麼難度,系統封裝好了處理數據和線程的功能,只需按照步驟把要執行的邏輯放進去就行了,如今來看看AsyncTask 是如何處理了複雜邏輯而卻給咱們提供簡單的使用方法,咱們知道AsyncTask 的執行是從調用AsyncTask().execute()開始的,一塊兒來看看他的源碼吧:android
@MainThread
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
return executeOnExecutor(sDefaultExecutor, params);
}
@MainThread
public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
Params... params) {
if (mStatus != Status.PENDING) { //判斷此時的AsyncTask對象的狀態
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; //標記AsyncTask對象爲運行狀態
onPreExecute();
mWorker.mParams = params; //設置任務參數
exec.execute(mFuture);
return this;
}複製代碼
從源碼中能夠看出execute()的方法執行過程:數組
上述所述的執行過程外,方法中還出現了三個變量:sDefaultExecutor 、mWorker、mFuture,從變量的名稱和執行的操做咱們姑且能夠猜想一下,sDefaultExecutor 應該爲任務的直接執行者(即線程、線程池)或間接調用線程執行,mWork對執行參數的封裝,mFuture是在exec.execute(mFuture)中執行的,因此應該Runnable類的實例,三個對象實現了任務的保存、獲取、執行者、如何執行;那若是咱們搞懂了這幾個類的工做過程也就搞懂了AsyncTask的實現。bash
3.1 sDefaultExecutor app
public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
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);
}
}
}
複製代碼
private static final BlockingQueue<Runnable> sPoolWorkQueue =
new LinkedBlockingQueue<Runnable>(128); // 任務隊列
private static final ThreadFactory sThreadFactory = new ThreadFactory() { // 生成命名的線程
private final AtomicInteger mCount = new AtomicInteger(1);
public Thread newThread(Runnable r) {
return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());
}
};
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;
}複製代碼
上述爲手動建立線程池的基本過程,還記得前面的Log中執行onBackground()的線程 AsyncTask #1嗎;就是在這個地方建立的,也間接說明了真正執行任務的是線程池ide
忽略參數細節處理的話,到此Async的執行流程基本出來了,首先調用execute()方法 --> 判斷狀態是否爲PENDING -->調用prepare準備數據 -->函數
3.2 mWorkeroop
從上面的賦值能夠看出,mWork保存了AsyncTask傳入的參數params,下面看看它是如何執行的:源碼分析
private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {
Params[] mParams;
}
mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
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;
}
};複製代碼
private Result postResult(Result result) {
@SuppressWarnings("unchecked")
Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
new AsyncTaskResult<Result>(this, result));
message.sendToTarget();
return result;
}複製代碼
3.2 mFuturepost
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);
}
}
};複製代碼
還記的前面的判斷嗎?mFuture 爲Runnable的對象,在AsyncTask中一樣也實例化了mFuture的對象,實現done()方法,調用 postResultIfNotInvoked()傳遞結果:ui
private void postResultIfNotInvoked(Result result) {
final boolean wasTaskInvoked = mTaskInvoked.get();
if (!wasTaskInvoked) {
postResult(result);
}
}複製代碼
3.4 線程池執行mFuture
public void run() {
if (state != NEW ||
!U.compareAndSwapObject(this, RUNNER, null, Thread.currentThread()))
return;
try {
Callable<V> c = callable;
if (c != null && state == NEW) {
V result;
boolean ran;
try {
result = c.call();//調用call()
ran = true;
} catch (Throwable ex) {
result = null;
ran = false;
setException(ex);
}
if (ran)
set(result);
}
} finally {
runner = null;
int s = state;
if (s >= INTERRUPTING)
handlePossibleCancellationInterrupt(s);
}
}複製代碼
到此AsyncTask的參數處理、任務執行和結果的傳遞都介紹完畢了,相信你們對此過程應該有所瞭解了,所剩部分就是AsyncTask的線程切換了,前面也提到了是利用Handler實現的,一塊兒看看吧
3.5 線程的切換
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;
}
}
}複製代碼
protected final void publishProgress(Progress... values) {
if (!isCancelled()) {
getHandler().obtainMessage(MESSAGE_POST_PROGRESS,
new AsyncTaskResult<Progress>(this, values)).sendToTarget();
}
}複製代碼
好了,大功告成,全部的內容講完了,有沒有感受代碼封裝的奇妙之處呢?有沒想本身嘗試一下寫一個簡單的AsyncTask呢?心動不如行動,一塊兒實現一個簡單的AsyncTask類吧
代碼以下:
/**
* @author : Alex
* @date : 2018/08/25
* @version : V 2.0.0
*/
const val PROGRESS = 100
const val RESULT = 101
abstract class SimpleAsyncTask<Params, Progress, Result> {
val handler = object : Handler(Looper.getMainLooper()) {
override fun handleMessage(msg: Message?) {
super.handleMessage(msg)
when (msg?.what) {
PROGRESS -> onProgressUpdate(msg.obj as Progress)
RESULT -> onPostExecute(msg.obj as Result)
}
}
}
open fun onPreExecute() {
}
open abstract fun doInBackground(params: Array<Int>): Result
open fun onProgressUpdate( progress: Progress) {
}
open fun onPostExecute(result: Result) {
}
fun postResult(result: Result) {
val msg = handler.obtainMessage(RESULT, result)
handler.sendMessage(msg)
}
fun publishProgress(progress: Progress) {
val msg = handler.obtainMessage(PROGRESS, progress)
handler.sendMessage(msg)
}
fun execute(params: Array<Int>) {
onPreExecute()
Thread {
postResult(doInBackground(params))
}.start()
}
}複製代碼
將上面例子中改成繼承SimpleAsyncTask,執行結果與AsyncTask執行結果同樣:
例子很是簡單也體現了執行的過程和邏輯,好了本次到此結束。