配色: 字号:
AsyncTask实现机制
2016-12-17 | 阅:  转:  |  分享 
  
AsyncTask实现机制





publicfinalAsyncTaskexecute(Params...params){

returnexecuteOnExecutor(sDefaultExecutor,params);

}



publicfinalAsyncTaskexecuteOnExecutor(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{

finalArrayDequemTasks=newArrayDeque();

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(){

publicResultcall()throwsException{

mTaskInvoked.set(true);



Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);

//noinspectionunchecked

returnpostResult(doInBackground(mParams));

}

};



mFuture=newFutureTask(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(this,result));

message.sendToTarget();

returnresult;

}



主线程中创建InternalHandler并发送MESSAGE_POST_RESULT消息,然后调用finish函数



privatestaticclassInternalHandlerextendsHandler{

publicInternalwww.wang027.comHandler(){

super(Looper.getMainLooper());

}



@SuppressWarnings({"unchecked","RawUseOfParameterizedType"})

@Override

publicvoidhandleMessage(Messagemsg){

AsyncTaskResultresult=(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(!isCancewww.baiyuewang.netlled()){

getHandler().obtainMessage(MESSAGE_POST_PROGRESS,

newAsyncTaskResult(this,values)).sendToTarget();

}

}



privatestaticclassInternalHandlerextendsHandler{

publicInternalHandler(){

super(Looper.getMainLooper());

}



@SuppressWarnings({"unchecked","RawUseOfParameterizedType"})

@Override

publicvoidhandleMessage(Messagemsg){

AsyncTaskResultresult=(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;

}

}

}

献花(0)
+1
(本文系thedust79首藏)