linux异步实现原理,Android异步处理四:AsyncTask的实现原理
分析:
在分析實現流程之前,我們先了解一下AsyncTask有哪些成員變量。
privatestaticfinalintCORE_POOL_SIZE?=5;//5個核心工作線程
privatestaticfinalintMAXIMUM_POOL_SIZE?=128;//最多128個工作線程
privatestaticfinalintKEEP_ALIVE?=1;//空閑線程的超時時間為1秒
privatestaticfinalBlockingQueue?sWorkQueue?=
newLinkedBlockingQueue(10);//等待隊列
privatestaticfinalThreadPoolExecutorsExecutor?=newThreadPoolExecutor(CORE_POOL_SIZE,
MAXIMUM_POOL_SIZE,?KEEP_ALIVE,?TimeUnit.SECONDS,?sWorkQueue,sThreadFactory);//線程池是靜態變量,所有的異步任務都會放到這個線程池的工作線程內執行。
回到例子中,點擊按鈕之后會新建一個GetCSDNLogoTask對象:
GetCSDNLogoTask?task?=newGetCSDNLogoTask();
此時會調用父類AsyncTask的構造函數:
AsyncTask.java
publicAsyncTask()?{
mWorker?=newWorkerRunnable()?{
publicResult?call()throwsException?{
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
returndoInBackground(mParams);
}
};
mFuture?=newFutureTask(mWorker)?{
@Override
protectedvoiddone()?{
Message?message;
Result?result?=null;
try{
result?=?get();
}catch(InterruptedException?e)?{
Android.util.Log.w(LOG_TAG,?e);
}catch(ExecutionException?e)?{
thrownewRuntimeException("An?error?occured?while?executing?doInBackground()",
e.getCause());
}catch(CancellationException?e)?{
message?=?sHandler.obtainMessage(MESSAGE_POST_CANCEL,
newAsyncTaskResult(AsyncTask.this,?(Result[])null));
message.sendToTarget();//取消任務,發送MESSAGE_POST_CANCEL消息
return;
}catch(Throwable?t)?{
thrownewRuntimeException("An?error?occured?while?executing?"
+"doInBackground()",?t);
}
message?=?sHandler.obtainMessage(MESSAGE_POST_RESULT,
newAsyncTaskResult(AsyncTask.this,?result));//完成任務,發送MESSAGE_POST_RESULT消息并傳遞result對象
message.sendToTarget();
}
};
}
WorkerRunnable類實現了callable接口的call()方法,該函數會調用我們在AsyncTask子類中實現的doInBackground(mParams)方法,由此可見,WorkerRunnable封裝了我們要執行的異步任務。FutureTask中的protected void done() {}方法實現了異步任務狀態改變后的操作。當異步任務被取消,會向UI線程傳遞MESSAGE_POST_CANCEL消息,當任務成功執行,會向UI線程傳遞MESSAGE_POST_RESULT消息,并把執行結果傳遞到UI線程。
由此可知,AsyncTask在構造的時候已經定義好要異步執行的方法doInBackground(mParams)和任務狀態變化后的操作(包括失敗和成功)。
當創建完GetCSDNLogoTask對象后,執行
task.execute("http://www.linuxidc.com/pic/logo.gif");
此時會調用AsyncTask的execute(Params...params)方法
AsyncTask.java
publicfinalAsyncTask?execute(Params...?params)?{
if(mStatus?!=?Status.PENDING)?{
switch(mStatus)?{
caseRUNNING:
thrownewIllegalStateException("Cannot?execute?task:"
+"?the?taskis?already?running.");
caseFINISHED:
thrownewIllegalStateException("Cannot?execute?task:"
+"?the?taskhas?already?been?executed?"
+"(a?task?canbe?executed?only?once)");
}
}
mStatus?=?Status.RUNNING;
onPreExecute();//運行在ui線程,在提交任務到線程池之前執行
mWorker.mParams?=?params;
sExecutor.execute(mFuture);//提交任務到線程池
returnthis;
}
當任務正在執行或者已經完成,會拋出IllegalStateException,由此可知我們不能夠重復調用execute(Params...params)方法。在提交任務到線程池之前,調用了onPreExecute()方法。然后才執行sExecutor.execute(mFuture)是任務提交到線程池。
前面我們說到,當任務的狀態發生改變時(1、執行成功2、取消執行3、進度更新),工作線程會向UI線程的Handler傳遞消息。在《Android異步處理三:Handler+Looper+MessageQueue深入詳解》一文中我們提到,Handler要處理其他線程傳遞過來的消息。在AsyncTask中,InternalHandler是在UI線程上創建的,它接收來自工作線程的消息,實現代碼如下:
AsyncTask.java
privatestaticclassInternalHandlerextendsHandler?{
@SuppressWarnings({"unchecked","RawUseOfParameterizedType"})
@Override
publicvoidhandleMessage(Message?msg)?{
AsyncTaskResult?result?=(AsyncTaskResult)?msg.obj;
switch(msg.what)?{
caseMESSAGE_POST_RESULT:
//?There?is?onlyone?result
result.mTask.finish(result.mData[0]);//執行任務成功
break;
caseMESSAGE_POST_PROGRESS:
result.mTask.onProgressUpdate(result.mData);//進度更新
break;
caseMESSAGE_POST_CANCEL:
result.mTask.onCancelled();//取消任務
break;
}
}
}
當接收到消息之后,AsyncTask會調用自身相應的回調方法。
總結:
1、 AsyncTask的本質是一個靜態的線程池,AsyncTask派生出的子類可以實現不同的異步任務,這些任務都是提交到靜態的線程池中執行。
2、線程池中的工作線程執行doInBackground(mParams)方法執行異步任務
3、當任務狀態改變之后,工作線程會向UI線程發送消息,AsyncTask內部的InternalHandler響應這些消息,并調用相關的回調函數
總結
以上是生活随笔為你收集整理的linux异步实现原理,Android异步处理四:AsyncTask的实现原理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql 查看当前数据库编码方式_My
- 下一篇: win10右键一直转圈_Win10总是自