7 0 AsyncTask原始碼分析

2021-07-28 14:03:05 字數 3938 閱讀 5802

之前開發中經常使用asynctask進行非同步資料獲取,當時只限於使用,只知道大體的就是通過執行緒池+handler實現的封裝,具體的**細節沒有仔細看過,今天就閱讀一下原始碼,當作筆記。加深記憶

public

asynctask()

};mfuture = new futuretask(mworker) catch (interruptedexception e) catch (executionexception e) catch (cancellationexception e) }};

}

首先看workerrunnable,實現了callable介面

private

static

abstract

class

workerrunnable

implements

callable

再看一下首先看workerrunnable的初始化,由於是乙個抽象類,需要實現內部方法,具體方法裡面的實現是將mtaskinvoked設定為true,然後呼叫doinbackground方法,然後將doinbackground返回的結果集傳參給postresult方法並返回。

我們看一下postresult方法到底是個什麼

private result postresult(result result)
postresult方法內部建立了一條訊息,message.what=message_post_result,message.obj=new asynctaskresult(this, result),然後通過非同步訊息機制將訊息傳遞出去。

那我們傳遞出去的obj又是個什麼呢

private

static

class asynctaskresult

}

乙個很普通的類,就是將傳入的引數儲存一下

我們看一下處理訊息的handler

private

static handler gethandler()

return shandler;}}

private

static

class

internalhandler

extends

handler

@suppresswarnings()

@override

public

void

handlemessage(message msg)

}}

看handlemessage方法,接收到之前的what引數message_post_result,執行finish方法,我們看一下finish方法幹了哪些事

private

void

finish(result result) else

mstatus = status.finished;

}

邏輯很簡單,判斷任務是否取消,如果取消就執行oncancelled方法,如果沒有取消就onpostexecute,最後將狀態更改為結束狀態

我們在次回到構造方法中,workerrunnable初始化完成之後開始進行futuretask的任務初始化,將mworker當做構造引數傳入,覆寫done方法

protected

void

done() catch (interruptedexception e) catch (executionexception e) catch (cancellationexception e)

在mworker中的任務執行完畢之後會執行postresultifnotinvoked方法,我們接著再看一下這個方法發生了什麼:

private

void

postresultifnotinvoked(result result)

}

方法也比較簡單,會去判斷mtaskinvoked的true或false,mworker執行完畢之後已經將mtaskinvoked設定了為true,所以if裡面的語句一般是執行不到的

到這非同步任務的初始化分析已經完成了,接著非同步任務初始化完成之後我們需要去執行他,也就是execute方法:

public final asynctask<

params, progress, result> execute(params

...params)

方法內部其實是呼叫了executeonexecutor方法,我們再看一下這個方法:

public final asynctaskexecuteonexecutor(executor exec,

params... params)

}mstatus = status.running;

onpreexecute();

mworker.mparams = params;

exec.execute(mfuture);

return

this;

}

看核心部分exec.execute(mfuture),exec指向的是乙個serialexecutor例項

private

static

class

serialexecutor

implements

executor finally

}});

if (mactive == null)

}protected

synchronized

void

schedulenext()

}}

在serialexecutor內部維護了乙個任務佇列,通過offer方法將任務新增到隊尾,任務執行完之後呼叫schedulenext方法,schedulenext方法內部將任務佇列的隊首任務取出,如果不為空的話就通過thread_pool_executor去執行這個任務

這個thread_pool_executor又是什麼呢

public

static

final executor thread_pool_executor;

static

通過靜態塊去初始化了乙個執行緒池,看一下執行緒池的引數

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;

private

static

final blockingqueuespoolworkqueue =

new linkedblockingqueue(128);

理想情況下核心執行緒數為4個,最大執行緒併發數是cpu數乘以2然後減1,最大支援4*2+1=9個的執行緒數,空閒執行緒存活時間為30s,然後還有乙個長度128的執行緒佇列,當我們有多個任務需要執行execute的時候,execute方法是乙個同步方法,第乙個任務入隊,由poll取出執行,第二個任務需要等待第乙個任務執行完畢之後才能執行,所以execute方法是任務序列。

在開發中大部分的情況是並行的,又要怎麼樣才能進行並行操作呢,我們可以直接使用executeonexecutor方法執行任務,只需要指定乙個執行緒池跟引數即可,我們可以用原始碼中提供的thread_pool_executor,這樣就可以實現任務的並行。

AsyncTask原始碼分析

就從asynctask的構造方法開始分析 creates a new asynchronous task.this constructor must be invoked on the ui thread.public asynctask mfuture new futuretask mworker...

AsyncTask原始碼解析

public class requestinternetdata extends asynctask 後台執行的方法,可以執行非ui執行緒,可以執行耗時的方法。在這個方法裡面執行我們的具體任務 可以看到這裡傳進來的是多個引數,這裡對應我們在呼叫方法的時候可以傳進來多個引數,後面會看到 overrid...

AsyncTask 原始碼分析

asynctask 內部實現原理主要是兩個執行緒池和乙個handler。兩個執行緒池分別為serialexecutor和threadpoolexecutor。其中serialexecutor是維護乙個有序佇列 threadpoolexecutor是執行任務的執行緒池。handler是internal...