android中只能在主線程中進行ui操作,如果是其它子執行緒,需要借助非同步訊息處理機制handler。除此之外,還有個非常方便的asynctask
類,這個類內部封裝了handler
和執行緒池。本文先簡要介紹asynctask
的用法,然後分析具體實現。
asynctask
是乙個抽象類,我們需要建立子類去繼承它,並且重寫一些方法。asynctask
接受三個泛型引數:
除了指定泛型引數,還需要根據需要重寫一些方法,常用的如下:
下面分析這個類的實現,主要有執行緒池以及handler
兩部分。
當執行乙個asynctask
的時候呼叫的是execute()
方法,就從這個開始看:
public final asynctaskexecute(params... params)
public final asynctaskexecuteonexecutor(executor exec,
params... params)
} mstatus = status.running;
//先執行 onpreexecute
onpreexecute();
mworker.mparams = params;
exec.execute(mfuture);
return this;
}
execute
方法會呼叫executeonexecutor
。在這個方法中先檢查任務是否已經執行或者執行結束,然後把任務標記為running
。最開始執行的是onpreexecute
,接著把引數賦值給mworker
物件。這個mworker
是乙個callable
物件,最終被包裝為futuretask
,**如下:
private static abstract class workerrunnableimplements callable
mworker = new workerrunnable()
};mfuture = new futuretask(mworker) catch (interruptedexception e) catch (executionexception e) catch (cancellationexception e)
} };
從上面的**可以看出,在mworker
物件中的call()
方法會呼叫doinbackground
,返回值交給postresult
方法,這個方法通過handler
傳送訊息,這一點稍後再詳細分析。
在mworker
物件被封裝成futuretask
之後交由執行緒池執行,從execute
方法可以看出,使用的是sdefaultexecutor
,它的值預設為serial_executor
,也就是序列執行器,實現如下:
private static class serialexecutor implements executor finally
} });
if (mactive == null)
} protected synchronized void schedulenext()
} }public static final executor thread_pool_executor
= new threadpoolexecutor(core_pool_size, maximum_pool_size, keep_alive,
timeunit.seconds, spoolworkqueue, sthreadfactory);
在上面的**中,如果有任務執行,那麼serialexecutor
的execute
方法會被呼叫,它的邏輯是把runnable
物件加入arraydeque
佇列中,然後判斷mactivie
是否為空。第一次執行時mactive
當然為空,所以執行schedulenext
,其實就是取出任務佇列中的第乙個任務交給執行緒池(thread_pool_executor
)執行。加入mtask
佇列的runnable
物件的run
方法裡最終一定會呼叫schedulenext
,那麼又會從任務佇列中取出隊頭任務執行。這樣便實現了單執行緒順序執行任務,所以在asynctask
中預設啟用的是單執行緒執行,只有上乙個任務執行後才會執行下乙個任務。如果想要啟用多執行緒執行任務,可以直接呼叫executeonexecutor(executor exec, params... params)
,這裡的executor
引數可以使用asynctask
自帶的thread_pool_executor
,也可以自己定義。
asynctask
內部用handler
傳遞訊息,它的實現如下:
private static class internalhandler extends handler )
@override
public void handlemessage(message msg)
} }
如果訊息型別是任務執行後的返回值(message_post_result
)將呼叫finish()
方法:
private void finish(result result) else
mstatus = status.finished;
}
從上面可以知道,如果任務取消了,將呼叫oncancelled
,否則呼叫onpostexecute
,所以乙個asynctask
任務如果取消了,那麼onpostexecute
將不會得到執行。
如果訊息型別是執行進度(message_post_progress
)將呼叫onprogressupdate
,這個方法預設是空方法,我們可以根據自己的需要重寫。
asynctask
的主要邏輯就如上面所分析的,總結幾個需要注意的地方:
android原始碼分析—帶你認識不一樣的asynctask
android asynctask完全解析,帶你從原始碼的角度徹底理解
Cartographer原始碼篇 原始碼分析 1
在安裝編譯cartographer 1.0.0的時候,我們可以看到 主要包括cartorgarpher ros cartographer ceres sover三個部分。其中,ceres solver用於非線性優化,求解最小二乘問題 cartographer ros為ros平台的封裝,獲取感測器資料...
AbstractListView原始碼分析3
normal list that does not indicate choices public static final int choice mode none 0 the list allows up to one choice public static final int choice ...
SpringCloud Nacos原始碼分析
開啟 為什麼這樣修改引數,那就要檢視原始碼了!systemutils類 the system property name of standalone mode public static final string standalone mode property name nacos.standal...