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; } } }
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!