1. References
1. http://developer.android.com/reference/android/os/AsyncTask.html
2. http://blog.csdn.net/pi9nc/article/details/12622797
3. Http://www.tuicool.com/articles/VnMf2i3
The following detailed analysis of Asynctask source flow. The important things we need to know when reading the source code are the input and output (parameters), and the program entry (where the call is entered).
2 Pass the three generic parameters (1) Params, the type of the parameters sent to the task upon execution. This article passes the URL data
(2) Progress, the type of the Progress units published during the background computation.//progress bar
(3) result, the type of the result of the background computation. Results
3 methods available to external calls these functions have many features Daniel has explained because of the length of the reason is not to repeat:
/** * Override This method to perform a computation on a background thread. The * specified parameters is the parameters passed to {@link #execute} * By the caller of this task. Parameters are passed to execute Method parameter See method name this method is called in the non-main thread * * This methods can call {@link #publishProgress} to publish updates * on the UI thread . * * @param params the parameters of the task. Task parameters such as different URLs * * @return A result, defined by the subclass of this task. Result * */protected abstract Result doinbackground (params ... params); /** * Runs on the UI thread before {@link #doInBackground}. * Run on UI thread in call Doinbackground */protected void OnPreExecute () {}/** * <p>runs on the UI thread aft er {@link #doInBackground}. The * specified result is the value returned by {@link #doInBackground}.</p> * * <p>this method W On ' t is invoked if the task was cancelled.</p> * * @param result The result of the operation ComputeD by {@link #doInBackground}. */@SuppressWarnings ({"Unuseddeclaration"}) protected void OnPostExecute (result result) {}/** * Runs on The UI thread after {@link #publishProgress} is invoked. * The specified values is the values passed to {@link #publishProgress}. * * @param values the values indicating progress. Generic parameter is progress bar * */@SuppressWarnings ({"Unuseddeclaration"}) protected void Onprogressupdate (Progress ... values) {}
4. The program entry, such as http://blog.csdn.net/nothingl3/article/details/44415195, is invoked when the task is executed as follows:Newdownloadfilestask (). Execute (URL);
It is obvious that the Execute method of Asynctask was called. 5 Source ReadingTo jump into this method from the program Portal:
Public final Asynctask<params, Progress, result> execute (params ... params) { return Executeonexecutor ( Sdefaultexecutor, params); }
A sentence starts to jump:
Public final Asynctask<params, Progress, result> executeonexecutor (Executor exec, params ... params) { if (Mstatus! = status.pending) { switch (mstatus) {case RUNNING: throw new IllegalStateException ("Cannot execute task:" + "the task is Already running. "); Case finished: throw new IllegalStateException ("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; }
Line 3-13 is to check if the task starts reasonably 17 lines are called:
OnPreExecute ();
Obviously the method is called on the main thread. 19 Rows update the Mworker parameter (the object that implements this as the callable interface is mentioned later). 20 behavior
Exec.execute (mfuture);
Look and start jumping again. EXEC is the parameter for the transfer:
Sdefaultexecutor
So then jump in:
public static final Executor serial_executor = new Serialexecutor ();p rivate static volatile Executor Sdefaultexecutor = SE Rial_executor;
A few jumps I put the source in a stacked together. It can be seen that Exec.execute (mfuture) performed the Serialexecutor Excute method//Note that the parameter mfuture will be referred to in detail later.
private static class Serialexecutor implements Executor { final arraydeque<runnable> mtasks = new Arraydeque< ; Runnable> (); Runnable mactive; Public synchronized void Execute (final Runnable R) { Mtasks.offer (new Runnable () {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);}}}
The Mtask is a double-ended queue of Arraydeque for the runnable array. However, the Synchronized keyword is added before the method name when there is thread insecurity. Mtask.offerAdding an element to the end of the array is added to each element. Here every time you go back to create a thread. Executes the r.run in the thread run method. The point is that R is the Mfutrue mentioned earlier. Find the next source of this member variable.
Private final futuretask<result> mfuture;mfuture = new Futuretask<result> (mworker) { &NB Sp @Override protected void done () { Try { postresultifnotinvoked (ge T ()); } catch (Interruptedexception e) { ANDROID.UTIL.LOG.W (Log_tag, E); catch (executionexception e) { throw new Ru Ntimeexception ("An error occured while executing doinbackground ()", E.getcause ()); } catch ( Cancellationexception e) { postresultifnotinvoked (null); &NBS P } } }; }
Let's see what Futruetask is. If you are familiar with multi-threaded children's shoes will not be unfamiliar.Futuretask is a runnablefuture<v>, and Runnablefuture realizes the Runnbale and realizes the futrue<v> of the two interfaces.
public class Futuretask<v> implements runnablefuture<v> public interface runnablefuture<v> Extends Runnable, future<v> {/** * sets this future to the result of its computation * unless it have be En cancelled. * /void run ();
Here the source code mfuture = new Futuretask<result> (mworker) is called
Public Futuretask (callable<v> callable)
Mworker implements the callable method. For specific mfuture How to call the callable method see:Http://www.tuicool.com/articles/VnMf2i3Mfuture calls the Mworker call method:
Mworker = new Workerrunnable<params, result> () {public Result call () throws Exception { Mtaskinvoked.set ( true); Process.setthreadpriority (process.thread_priority_background); Noinspection unchecked return Postresult (Doinbackground (Mparams)); } ;
Someone would wonder how mwork could have implemented the callable method? See here:
private static abstract class Workerrunnable<params, Result> implements callable<result> { params[] Mparams; }
The callable interface is similar to runnable. However, the greatest benefit is that the call method of the callable interface has a return value. Go back to the call method of Mworker. Returned to Postresult (Doinbackground (mparams)) Here we first call ourDoinbackground (Mparams) obviously here in the non-main thread so it can handle the time-consuming task and finally return the result by Postresult
Private result Postresult (result result) { @SuppressWarnings ("unchecked") message message = Shandler.obtainmessage (Message_post_result, new asynctaskresult<result> (this, RESULT)); Message.sendtotarget (); return result; }
We found that we were familiar with the message by Shandler.
private static class Internalhandler extends Handler { @SuppressWarnings ({"Unchecked", "Rawuseofparameterizedtype "}) @Override public void Handlemessage (Message msg) { Asynctaskresult result = (Asynctaskresult) msg.obj; switch (msg.what) {case Message_post_result: //There are only one RESULT result.mTask.finish ( Result.mdata[0]); break; Case message_post_progress: result.mTask.onProgressUpdate (result.mdata); Break;}}}
result is a Asynctaskresult<data> object that is passed in to the new asynctaskresult<result> (this, result)
private static class Asynctaskresult<data> { final asynctask mtask; Final data[] Mdata; Asynctaskresult (asynctask task, data ... data) { mtask = task; Mdata = data; } }
Back to the Handlemessage method. Because the message sent by Postresult Msg.what for Message_post_result, jump to
private void finish (result result) { if (iscancelled ()) { oncancelled (result); } else { OnPostExecute (result); } Mstatus = status.finished; }
Here to determine whether the task is cancelled or not, call OnPostExecute (result); Yes, call oncancelled (Result), and update the state. Done here. Back to Handlemessage Message_post_progress, who sent it?
Protected final void publishprogress (Progress ... values) { if (!iscancelled ()) { Shandler.obtainmessage ( Message_post_progress, New asynctaskresult<progress> (this, values)). Sendtotarget (); } }
When was it called? Children's shoes with Asynctask will remember. We'll call it in the Doinbackgroud method.publishprogress () method. The whole Asynctask method reads complete. But some pits. For example, why use thread pool +futuretask way. Another example
public static final Executor thread_pool_executor = new Threadpoolexecutor (core_pool_size, Maximum_pool_size, KEEP _alive, timeunit.seconds, Spoolworkqueue, sthreadfactory);
The number of thread pools here is different from the previous 3.0 version Asynctask settings.
ps:http://blog.csdn.net/mylzc/article/details/6784415
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Asynctask Source Reading