Android:asynctask Source Code Analysis

Source: Internet
Author: User
<span id="Label3"></p>Simple example<pre class="prettyprint"><code class=" hljs axapta"><span class="hljs-keyword"><span class="hljs-keyword">Private</span></span> <span class="hljs-class"><span class="hljs-class"> <span class="hljs-keyword">class</span> <span class="hljs-title">myasynctask</span> <span class="hljs-inheritance"><span class="hljs-keyword">extends</span></span> <span class="hljs-title">asynctask</span><<span class="hljs-title">String</span>,<span class="hljs-title">Void</span>, <span class="hljs-title"> String</span>>{</span></span>@Override<span class="hljs-keyword"><span class="hljs-keyword">protected</span></span>String Doinbackground (string ... params) {string<span class="hljs-keyword"><span class="hljs-keyword">Str</span></span>= params[<span class="hljs-number"><span class="hljs-number">0</span></span>];<span class="hljs-keyword"><span class="hljs-keyword">return</span></span> <span class="hljs-string"><span class="hljs-string">"disposed"</span></span>+<span class="hljs-keyword"><span class="hljs-keyword">Str</span></span>; } @Override<span class="hljs-keyword"><span class="hljs-keyword">protected</span></span> <span class="hljs-keyword"><span class="hljs-keyword">void</span></span>OnPostExecute (String S) {LOG.E (<span class="hljs-string"><span class="hljs-string">"TAG"</span></span>, s);<span class="hljs-keyword"><span class="hljs-keyword">Super</span></span>. OnPostExecute (s); }}</code></pre><pre class="prettyprint"><pre class="prettyprint"><code class=" hljs vbscript"><span class="hljs-keyword">new</span> MyAsyncTask().<span class="hljs-keyword">execute</span>(<span class="hljs-string">"leelit"</span>);</code></pre></pre>Internal logic<p><p>1, Instantiate asynctask,new Myasynctask ();</p></p><pre class="prettyprint"><code class=" hljs cs"><span class="hljs-keyword"><span class="hljs-keyword"></span> public</span> <span class="hljs-title"><span class="hljs-title">Asynctask</span></span>() {mworker =<span class="hljs-keyword"><span class="hljs-keyword">New</span></span>workerrunnable<params, result> () {<span class="hljs-keyword"><span class="hljs-keyword"></span> public</span>Result<span class="hljs-title"><span class="hljs-title">Pager</span></span>() throws Exception {mtaskinvoked.<span class="hljs-keyword"><span class="hljs-keyword">Set</span></span>(<span class="hljs-keyword"><span class="hljs-keyword">true</span></span>); Process.setthreadpriority (process.thread_priority_background);<span class="hljs-comment"><span class="hljs-comment">//noinspection Unchecked</span></span> <span class="hljs-keyword"><span class="hljs-keyword">return</span></span>Postresult (doinbackground (mparams)); } }; Mfuture =<span class="hljs-keyword"><span class="hljs-keyword">New</span></span>Futuretask<result> (mworker) {@Override<span class="hljs-keyword"><span class="hljs-keyword">protected</span></span> <span class="hljs-keyword"><span class="hljs-keyword">void</span></span> <span class="hljs-title"><span class="hljs-title"></span> done</span>() {<span class="hljs-keyword"><span class="hljs-keyword">Try</span></span>{postresultifnotinvoked (<span class="hljs-keyword"><span class="hljs-keyword">Get</span></span>()); }<span class="hljs-keyword"><span class="hljs-keyword">Catch</span></span>(interruptedexception E) {ANDROID.UTIL.LOG.W (log_tag, e); }<span class="hljs-keyword"><span class="hljs-keyword">Catch</span></span>(executionexception E) {<span class="hljs-keyword"><span class="hljs-keyword">Throw</span></span> <span class="hljs-keyword"><span class="hljs-keyword">New</span></span>RuntimeException (<span class="hljs-string"><span class="hljs-string">"an Error occured while executing doinbackground ()"</span></span>, E.getcause ()); }<span class="hljs-keyword"><span class="hljs-keyword">Catch</span></span>(cancellationexception E) {postresultifnotinvoked (<span class="hljs-keyword"><span class="hljs-keyword">NULL</span></span>); } } }; }</code></pre><p><p>constructor to instantiate two objects, the Mworker object implements the callable< Result>,mfuture here can be seen as a wrapper over mworker, he is a futuretask object.</p></p><p><p>2. Myasynctask.execute (params)</p></p><pre class="prettyprint"><pre class="prettyprint"><code class=" hljs lasso"> <span class="hljs-keyword">public</span> final AsyncTask<span class="hljs-subst"><</span><span class="hljs-keyword">Params</span>, Progress, Result<span class="hljs-subst">></span> execute(<span class="hljs-keyword">Params</span><span class="hljs-attribute">...</span><span class="hljs-keyword">params</span>) { <span class="hljs-keyword">return</span><span class="hljs-keyword">params</span>); }</code></pre></pre><pre class="prettyprint"><code class=" hljs cs"> <span class="hljs-keyword"><span class="hljs-keyword"></span> public</span>Final asynctask<params, Progress, result><span class="hljs-title"><span class="hljs-title">Executeonexecutor</span></span>(Executor exec, Params ...<span class="hljs-keyword"><span class="hljs-keyword">params</span></span>) {<span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(mstatus! = Status.pending) {<span class="hljs-keyword"><span class="hljs-keyword">Switch</span></span>(mstatus) {<span class="hljs-keyword"><span class="hljs-keyword"></span> case</span>RUNNING:<span class="hljs-keyword"><span class="hljs-keyword">Throw</span></span> <span class="hljs-keyword"><span class="hljs-keyword">New</span></span>IllegalStateException (<span class="hljs-string"><span class="hljs-string">"cannot Execute task:"</span></span>+<span class="hljs-string"><span class="hljs-string">"the task is already running."</span></span>);<span class="hljs-keyword"><span class="hljs-keyword"></span> case</span>Finished:<span class="hljs-keyword"><span class="hljs-keyword">Throw</span></span> <span class="hljs-keyword"><span class="hljs-keyword">New</span></span>IllegalStateException (<span class="hljs-string"><span class="hljs-string">"cannot Execute task:"</span></span>+<span class="hljs-string"><span class="hljs-string">"the task has already been executed"</span></span>+<span class="hljs-string"><span class="hljs-string">"(a task can be executed only once)"</span></span>); }} Mstatus = status.running; OnPreExecute (); Mworker.mparams =<span class="hljs-keyword"><span class="hljs-keyword">params</span></span>; Exec.execute (mfuture);<span class="hljs-keyword"><span class="hljs-keyword">return</span></span> <span class="hljs-keyword"><span class="hljs-keyword"></span> this</span>; }</code></pre><pre class="prettyprint"><pre class="prettyprint"><code class=" hljs cs"> <span class="hljs-keyword">private</span><span class="hljs-keyword">static</span><span class="hljs-keyword">volatile</span> Executor sDefaultExecutor = SERIAL_EXECUTOR;</code></pre></pre><p><p>The Execute method calls the Executeonexecutor method directly inside the Method:</p></p> <ul> <ul> <li>first, the state of the judgment and settings, here also shows that a Asynctask object can only execute once, or throw an exception;</li> <li>Then execute a onpreexecute () method, which is the first execution of the execution process that we can rewrite;</li> <li>Set Mworker parameters;</li> <li>The thread pool executes the Task.</li> </ul> </ul><p><p>Note that the exec here is passing in sdefaultexecutor, and Sdefaultexecutor = serial_executor, from the name you can see that he is a serial execution of the task, and then look down.</p></p><pre class="prettyprint"><pre class="prettyprint"><code class=" hljs java"><span class="hljs-keyword">public</span><span class="hljs-keyword">static</span><span class="hljs-keyword">final</span><span class="hljs-keyword">new</span> SerialExecutor();</code></pre></pre><pre class="prettyprint"><code class=" hljs java"> <span class="hljs-keyword"><span class="hljs-keyword">Private</span></span> <span class="hljs-keyword"><span class="hljs-keyword">Static</span></span> <span class="hljs-class"><span class="hljs-class"> <span class="hljs-keyword">class</span> <span class="hljs-title">serialexecutor</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Executor</span> {</span></span> <span class="hljs-keyword"><span class="hljs-keyword">Final</span></span>Arraydeque<runnable> Mtasks =<span class="hljs-keyword"><span class="hljs-keyword">New</span></span>Arraydeque<runnable> (); Runnable mactive;<span class="hljs-keyword"><span class="hljs-keyword"></span> public</span> <span class="hljs-keyword"><span class="hljs-keyword">synchronized</span></span> <span class="hljs-keyword"><span class="hljs-keyword">void</span></span> <span class="hljs-title"><span class="hljs-title">Execute</span></span>(<span class="hljs-keyword"><span class="hljs-keyword">Final</span></span>Runnable R) {mtasks.offer (<span class="hljs-keyword"><span class="hljs-keyword">New</span></span>Runnable () {<span class="hljs-keyword"><span class="hljs-keyword"></span> public</span> <span class="hljs-keyword"><span class="hljs-keyword">void</span></span> <span class="hljs-title"><span class="hljs-title">Run</span></span>() {<span class="hljs-keyword"><span class="hljs-keyword">Try</span></span>{r.run (); }<span class="hljs-keyword"><span class="hljs-keyword">finally</span></span>{schedulenext (); } } });<span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(mactive = =<span class="hljs-keyword"><span class="hljs-keyword">NULL</span></span>) {schedulenext (); } }<span class="hljs-keyword"><span class="hljs-keyword">protected</span></span> <span class="hljs-keyword"><span class="hljs-keyword">synchronized</span></span> <span class="hljs-keyword"><span class="hljs-keyword">void</span></span> <span class="hljs-title"><span class="hljs-title">Schedulenext</span></span>() {<span class="hljs-keyword"><span class="hljs-keyword">if</span></span>((mactive = Mtasks.poll ())! =<span class="hljs-keyword"><span class="hljs-keyword">NULL</span></span>) {thread_pool_executor.execute (mactive); } } }</code></pre><p><p>The above code is still better understood, is the implementation of the serial implementation of the TASK. The thread pool inside thread_pool_executor, Each version will be different, but most of the task queue is set at 128.</p></p><pre class="prettyprint"><code class=" hljs java"> <span class="hljs-keyword"><span class="hljs-keyword">Private</span></span> <span class="hljs-keyword"><span class="hljs-keyword">Static</span></span> <span class="hljs-keyword"><span class="hljs-keyword">Final</span></span> <span class="hljs-keyword"><span class="hljs-keyword">int</span></span>Core_pool_size = Cpu_count +<span class="hljs-number"><span class="hljs-number">1</span></span>;<span class="hljs-keyword"><span class="hljs-keyword">Private</span></span> <span class="hljs-keyword"><span class="hljs-keyword">Static</span></span> <span class="hljs-keyword"><span class="hljs-keyword">Final</span></span> <span class="hljs-keyword"><span class="hljs-keyword">int</span></span>Maximum_pool_size = Cpu_count *<span class="hljs-number"><span class="hljs-number">2</span></span>+<span class="hljs-number"><span class="hljs-number">1</span></span>;<span class="hljs-keyword"><span class="hljs-keyword">Private</span></span> <span class="hljs-keyword"><span class="hljs-keyword">Static</span></span> <span class="hljs-keyword"><span class="hljs-keyword">Final</span></span> <span class="hljs-keyword"><span class="hljs-keyword">int</span></span>Keep_alive =<span class="hljs-number"><span class="hljs-number">1</span></span>;<span class="hljs-keyword"><span class="hljs-keyword">Private</span></span> <span class="hljs-keyword"><span class="hljs-keyword">Static</span></span> <span class="hljs-keyword"><span class="hljs-keyword">Final</span></span>Blockingqueue<runnable> Spoolworkqueue =<span class="hljs-keyword"><span class="hljs-keyword">New</span></span>Linkedblockingqueue<runnable> (<span class="hljs-number"><span class="hljs-number"></span> -</span>);<span class="hljs-keyword"><span class="hljs-keyword"></span> public</span> <span class="hljs-keyword"><span class="hljs-keyword">Static</span></span> <span class="hljs-keyword"><span class="hljs-keyword">Final</span></span>Executor Thread_pool_executor =<span class="hljs-keyword"><span class="hljs-keyword">New</span></span>Threadpoolexecutor (core_pool_size, maximum_pool_size, keep_alive, timeunit.seconds, sPoolWorkQueue, sTh readfactory);</code></pre>Perform the whole process<p><p>1, Instantiate Myasynctask object, Instantiate Mworker object and Mfuture Object.<br>2, Call the Execute method, determine the setting state, execute the optional override of the OnPreExecute () method, set the parameters, internal thread pool execution task, Exec.execute (mfuture).<br>3, the implementation of Mworker inside the task, call Doinbackground (mparams) method, which is also must be rewritten,<br>4, Execute postresult method, send the message back to the main thread, postresult (doinbackground (mparams));</p></p><pre class="prettyprint"><pre class="prettyprint"><code class=" hljs java"> <span class="hljs-keyword">private</span><span class="hljs-title">postResult</span>(Result result) { <span class="hljs-annotation">@SuppressWarnings</span>(<span class="hljs-string">"unchecked"</span>) Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT, <span class="hljs-keyword">new</span> AsyncTaskResult<Result>(<span class="hljs-keyword">this</span>, result)); message.sendToTarget(); <span class="hljs-keyword">return</span> result; }</code></pre></pre><p><p>5, handler processing message, here to the end will be called to rewrite the need to process the main thread OnPostExecute (result);</p></p><pre class="prettyprint"><pre class="prettyprint"><code class=" hljs cs"> <span class="hljs-keyword">public</span><span class="hljs-keyword">void</span><span class="hljs-title">handleMessage</span>(Message msg) { AsyncTaskResult<?> result = (AsyncTaskResult<?>) msg.obj; <span class="hljs-keyword">switch</span> (msg.what) { <span class="hljs-keyword">case</span> MESSAGE_POST_RESULT: <span class="hljs-comment">// There is only one result</span> result.mTask.finish(result.mData[<span class="hljs-number">0</span>]); <span class="hljs-keyword">break</span>; <span class="hljs-keyword">case</span> MESSAGE_POST_PROGRESS: result.mTask.onProgressUpdate(result.mData); <span class="hljs-keyword">break</span>; } }</code></pre></pre><p><p>Another common method is publishprogress, which also sends a message via handler to the main thread to process</p></p><pre class="prettyprint"><pre class="prettyprint"><code class=" hljs cs">getHandler().obtainMessage(MESSAGE_POST_PROGRESS, <span class="hljs-keyword">new</span> AsyncTaskResult<Progress>(<span class="hljs-keyword">this</span>, values)).sendToTarget();</code></pre></pre>Summary<p><p>1, each Asynctask object can only perform one task, because its internal will have state judgment and set;<br>2, the internal shared a thread pool, the task queue is 128, sequential execution of tasks, but the final effect will look at the specific thread Pool.<br>3, instantiate the Asynctask object, the constructor is to instantiate a futuretask object, once run to execute a given callable. The callable object here is mworker, which is the implementation of the Doinbackground (mparams) method, which must be rewritten, and finally execute the Postresult method, send the message back to the main thread via handler, Postresult ( Doinbackground (mparams)).</p></p><p><p>Instantiating the Asynctask object is the instantiation of the task object, which invokes the overridden method internally;<br>The call execution method is the thread pool to perform the task, and finally completes the asynchronous communication through the Handler.</p></p> <p style="font-size:12px;"><p style="font-size:12px;">Copyright Notice: This article for Bo Master original article, without Bo Master permission not Reproduced.</p></p> <p><p>Android:asynctask Source Code Analysis</p></p></span>

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.