Android AsyncTask实现机制详细介绍及实例代码
AndroidAsyncTask实现机制
示例代码:
publicfinalAsyncTask<Params,Progress,Result>execute(Params...params){
returnexecuteOnExecutor(sDefaultExecutor,params);
}
publicfinalAsyncTask<Params,Progress,Result>executeOnExecutor(Executorexec,
Params...params){
if(mStatus!=Status.PENDING){
switch(mStatus){
caseRUNNING:
thrownewIllegalStateException("Cannotexecutetask:"
+"thetaskisalreadyrunning.");
caseFINISHED:
thrownewIllegalStateException("Cannotexecutetask:"
+"thetaskhasalreadybeenexecuted"
+"(ataskcanbeexecutedonlyonce)");
}
}
mStatus=Status.RUNNING;
onPreExecute();
mWorker.mParams=params;
exec.execute(mFuture);
returnthis;
}
execute先调用onPreExecute()(可见,onPreExecute是自动调用的)然后调用exec.execute(mFuture)
publicinterfaceExecutor{
voidexecute(Runnablecommand);
}
这是一个接口,具体实现在
privatestaticclassSerialExecutorimplementsExecutor{
finalArrayDeque<Runnable>mTasks=newArrayDeque<Runnable>();
RunnablemActive;
publicsynchronizedvoidexecute(finalRunnabler){
mTasks.offer(newRunnable(){
publicvoidrun(){
try{
r.run();
}finally{
scheduleNext();
}
}
});
if(mActive==null){
scheduleNext();
}
}
protectedsynchronizedvoidscheduleNext(){
if((mActive=mTasks.poll())!=null){
THREAD_POOL_EXECUTOR.execute(mActive);
}
}
}
从上面可知,AsyncTask执行过程如下:先执行onPreExecute,然后交给SerialExecutor执行。在SerialExecutor中,先把Runnable添加到mTasks中。
如果没有Runnable正在执行,那么就调用SerialExecutor的scheduleNext。同时当一个Runnable执行完以后,继续执行下一个任务
AsyncTask中有两个线程池,THREAD_POOL_EXECUTOR和SERIAL_EXECUTOR,以及一个Handler–InternalHandler
/**
*An{@linkExecutor}thatcanbeusedtoexecutetasksinparallel.
*/
publicstaticfinalExecutorTHREAD_POOL_EXECUTOR
=newThreadPoolExecutor(CORE_POOL_SIZE,MAXIMUM_POOL_SIZE,KEEP_ALIVE,
TimeUnit.SECONDS,sPoolWorkQueue,sThreadFactory);
/**
*An{@linkExecutor}thatexecutestasksoneatatimeinserial
*order.Thisserializationisglobaltoaparticularprocess.
*/
publicstaticfinalExecutorSERIAL_EXECUTOR=newSerialExecutor();
privatestaticInternalHandlersHandler;
SERIAL_EXECUTOR用于任务的排列,THREAD_POOL_EXECUTOR真正执行线程,InternalHandler用于线程切换
先看构造函数
publicAsyncTask(){
mWorker=newWorkerRunnable<Params,Result>(){
publicResultcall()throwsException{
mTaskInvoked.set(true);
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
//noinspectionunchecked
returnpostResult(doInBackground(mParams));
}
};
mFuture=newFutureTask<Result>(mWorker){
@Override
protectedvoiddone(){
try{
postResultIfNotInvoked(get());
}catch(InterruptedExceptione){
android.util.Log.w(LOG_TAG,e);
}catch(ExecutionExceptione){
thrownewRuntimeException("AnerroroccuredwhileexecutingdoInBackground()",
e.getCause());
}catch(CancellationExceptione){
postResultIfNotInvoked(null);
}
}
};
}
看到了熟悉的doInBackground了吧,然后调用postResult
privateResultpostResult(Resultresult){
@SuppressWarnings("unchecked")
Messagemessage=getHandler().obtainMessage(MESSAGE_POST_RESULT,
newAsyncTaskResult<Result>(this,result));
message.sendToTarget();
returnresult;
}
主线程中创建InternalHandler并发送MESSAGE_POST_RESULT消息,然后调用finish函数
privatestaticclassInternalHandlerextendsHandler{
publicInternalHandler(){
super(Looper.getMainLooper());
}
@SuppressWarnings({"unchecked","RawUseOfParameterizedType"})
@Override
publicvoidhandleMessage(Messagemsg){
AsyncTaskResult<?>result=(AsyncTaskResult<?>)msg.obj;
switch(msg.what){
caseMESSAGE_POST_RESULT:
//Thereisonlyoneresult
result.mTask.finish(result.mData[0]);
break;
caseMESSAGE_POST_PROGRESS:
result.mTask.onProgressUpdate(result.mData);
break;
}
}
}
privatevoidfinish(Resultresult){
if(isCancelled()){
onCancelled(result);
}else{
onPostExecute(result);
}
mStatus=Status.FINISHED;
}
finish中调用onPostExecute。
AsyncTask工作流程:newMyThread().execute(1);
先构造函数,然后execute
构造函数只是准备了mWorker和mFuture这两个变量
execute中调用onPreExecute,然后exec.execute(mFuture),其中响应了call函数,call中调用doInBackground,然后将结果传给Handler然后finish掉,finish函数调用onPostExecute
你可能会奇怪,为什么没有onProgressUpdate,有注解可以解释
/**
*RunsontheUIthreadafter{@link#publishProgress}isinvoked.
*Thespecifiedvaluesarethevaluespassedto{@link#publishProgress}.
*
*@paramvaluesThevaluesindicatingprogress.
*
*@see#publishProgress
*@see#doInBackground
*/
@SuppressWarnings({"UnusedDeclaration"})
protectedvoidonProgressUpdate(Progress...values){
}
也就是说必须调用publishProgress才会自动调用onProgressUpdate。
那如何调用publishProgress呢?
/**
*Overridethismethodtoperformacomputationonabackgroundthread.The
*specifiedparametersaretheparameterspassedto{@link#execute}
*bythecallerofthistask.
*
*Thismethodcancall{@link#publishProgress}topublishupdates
*ontheUIthread.
*
*@paramparamsTheparametersofthetask.
*
*@returnAresult,definedbythesubclassofthistask.
*
*@see#onPreExecute()
*@see#onPostExecute
*@see#publishProgress
*/
protectedabstractResultdoInBackground(Params...params);
doInBackground说的很明确,在doInBackground函数里面显示调用publishProgress即可。
publishProgress源码:
protectedfinalvoidpublishProgress(Progress...values){
if(!isCancelled()){
getHandler().obtainMessage(MESSAGE_POST_PROGRESS,
newAsyncTaskResult<Progress>(this,values)).sendToTarget();
}
}
privatestaticclassInternalHandlerextendsHandler{
publicInternalHandler(){
super(Looper.getMainLooper());
}
@SuppressWarnings({"unchecked","RawUseOfParameterizedType"})
@Override
publicvoidhandleMessage(Messagemsg){
AsyncTaskResult<?>result=(AsyncTaskResult<?>)msg.obj;
switch(msg.what){
caseMESSAGE_POST_RESULT:
//Thereisonlyoneresult
result.mTask.finish(result.mData[0]);
break;
caseMESSAGE_POST_PROGRESS:
//****************************************在这里调用
result.mTask.onProgressUpdate(result.mData);
break;
}
}
}
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!