Asynctask Implementation Mechanism

Source: Internet
Author: User

     PublicFinal Asynctask<params, Progress, result>Execute(Params ...params) {returnExecuteonexecutor (Sdefaultexecutor,params); } PublicFinal Asynctask<params, Progress, result>Executeonexecutor(Executor exec, Params ...params) {if(Mstatus! = status.pending) {Switch(Mstatus) { CaseRUNNING:Throw NewIllegalStateException ("Cannot execute task:"+"The task is already running."); CaseFinished:Throw NewIllegalStateException ("Cannot execute task:"+"The task has already been executed"+"(a task can be executed only once)");        }} mstatus = status.running;        OnPreExecute (); Mworker.mparams =params; Exec.execute (mfuture);return  This; }

Execute calls OnPreExecute () first (visible, OnPreExecute is automatically called) and then calls Exec.execute (Mfuture)

    publicinterface Executor {        void execute(Runnable command);    }

This is an interface, specifically implemented in

    Private Static  class serialexecutor implements Executor {        FinalArraydeque<runnable> Mtasks =NewArraydeque<runnable> (); Runnable mactive; Public synchronized void Execute(FinalRunnable r) {Mtasks.offer (NewRunnable () { Public void Run() {Try{R.run (); }finally{Schedulenext (); }                }            });if(Mactive = =NULL) {Schedulenext (); }        }protected synchronized void Schedulenext() {if((mactive = Mtasks.poll ())! =NULL) {Thread_pool_executor.execute (mactive); }        }    }

From the above, the Asynctask execution process is as follows: Execute the OnPreExecute first, then give Serialexecutor execution. In Serialexecutor, add runnable to Mtasks first.
If no runnable is executing, then call Serialexecutor's Schedulenext. At the same time, when a runnable executes, proceed to the next task

There are two thread pools in Asynctask, Thread_pool_executor and Serial_executor, and a Handler–internalhandler

    /** * A {@link Executor} that can is used to the execute tasks in parallel. */     Public Static FinalExecutor Thread_pool_executor =NewThreadpoolexecutor (Core_pool_size, Maximum_pool_size, Keep_alive, Timeunit.seconds, SPoolWorkQueue, sTh Readfactory);/** * An {@link Executor} This executes tasks one at a time in serial * order.     This serialization are global to a particular process. */     Public Static FinalExecutor Serial_executor =NewSerialexecutor ();Private StaticInternalhandler Shandler;

Serial_executor for the arrangement of tasks, thread_pool_executor real thread execution, Internalhandler for thread switching
First look at the constructor function

     Public Asynctask() {Mworker =NewWorkerrunnable<params, result> () { PublicResultPager() throws Exception {mtaskinvoked.Set(true); Process.setthreadpriority (Process.thread_priority_background);//noinspection Unchecked                returnPostresult (Doinbackground (mparams));        }        }; Mfuture =NewFuturetask<result> (mworker) {@Overrideprotected void  Done() {Try{postresultifnotinvoked (Get()); }Catch(Interruptedexception e)                {ANDROID.UTIL.LOG.W (Log_tag, E); }Catch(Executionexception e) {Throw NewRuntimeException ("An error occured while executing doinbackground ()", E.getcause ()); }Catch(Cancellationexception e) {postresultifnotinvoked (NULL);    }            }        }; }

See the familiar doinbackground, then call Postresult

    privatepostResult(Result result) {        @SuppressWarnings("unchecked")        Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,                new AsyncTaskResult<Result>(this, result));        message.sendToTarget();        return result;    }

The main thread creates the Internalhandler and sends the MESSAGE_POST_RESULT message, and then calls the Finish function

    Private Static  class internalhandler extends Handler {         Public Internalhandler() {Super(Looper.getmainlooper ()); }@SuppressWarnings({"Unchecked","Rawuseofparameterizedtype"})@Override         Public void Handlemessage(Message msg) {asynctaskresult<?> result = (asynctaskresult<?>) msg.obj;Switch(msg.what) { CaseMessage_post_result://There is only one resultResult.mTask.finish (result.mdata[0]); Break; CaseMESSAGE_POST_PROGRESS:result.mTask.onProgressUpdate (Result.mdata); Break; }        }    }Private void Finish(Result result) {if(IsCancelled ())        {oncancelled (result); }Else{OnPostExecute (result);    } mstatus = status.finished; }

Call OnPostExecute in finish.

Asynctask Workflow: New MyThread (). Execute (1);
First, the constructor is then execute
The constructor simply prepares the two variables mworker and mfuture
Execute calls OnPreExecute, and then Exec.execute (mfuture), which responds to the call function, calls Doinbackground and then passes the result to handler and then finish off, The Finish function calls OnPostExecute
You may wonder why there is no onprogressupdate, there are annotations to explain

    /**     * Runs on the UI thread after {@link #publishProgress} is invoked.     * The specified values are the values passed to {@link #publishProgress}.     *     * @param values The values indicating progress.     *     * @see #publishProgress     * @see #doInBackground     */    @SuppressWarnings({"UnusedDeclaration"})    protectedvoidonProgressUpdate(Progress... values) {    }

That is, you must call Publishprogress to call Onprogressupdate automatically.
So how do you call publishprogress?

/** * Override This method toPerform a computation onA background thread. The * specified parameters is theParameters passed to{@link#execute}* by  theCaller ofThis task. * * This method can call {@link#publishProgress} to publish updates* on  theUI thread. * * @param params the parameters of  theTask. *     * @returnAresult, defined by  theSubclass ofThis task. * * @see#onPreExecute ()* @see#onPostExecute* @see#publishProgress*/protected abstract Result doinbackground (params ... params);

Doinbackground said very clearly, in the Doinbackground function inside the call publishprogress can be displayed.
Publishprogress Source:

    protected Final void publishprogress(Progress ... values) {if(!iscancelled ()) {gethandler (). Obtainmessage (Message_post_progress,NewAsynctaskresult<progress> ( This, values). Sendtotarget (); }    }Private Static  class internalhandler extends Handler {         Public Internalhandler() {Super(Looper.getmainlooper ()); }@SuppressWarnings({"Unchecked","Rawuseofparameterizedtype"})@Override         Public void Handlemessage(Message msg) {asynctaskresult<?> result = (asynctaskresult<?>) msg.obj;Switch(msg.what) { CaseMessage_post_result://There is only one resultResult.mTask.finish (result.mdata[0]); Break; CaseMessage_post_progress://**************************************** is called hereResult.mTask.onProgressUpdate (Result.mdata); Break; }        }    }

Asynctask Implementation Mechanism

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.