Detailes using Android with AsyncTask Part2

You can see onCancelled () method will be called, onPostExecute (Result result) method will not be called.
The above describes the basic application AsyncTask, some friends may have doubts, AsyncTask internally how to perform it, process it performs what is the difference between using the Handler with us? The answer is: AsyncTask Thread + Handler is a good package, android.os.AsyncTask code can still see traces of Thread and Handler. Here to tell you in detail about the implementation of the principle of AsyncTask.
We look at the outline view AsyncTask:

We can see that the methods are crucial steps in which, doInBackground (Params ... params) is an abstract method, you must overwrite this method we have inherited AsyncTask; onPreExecute (), onProgressUpdate (Progress ... values), onPostExecute (Result result), onCancelled () method body these are empty, when we need to be able to selectively overwrite them; publishProgress (Progress ... values) is the final modification can not be overwritten only to call, we usually call doInBackground (Params ... params) in this method; in addition, we can see a Status enum class and getStatus () method, Status enum class code section as follows:

      // Initial state 
    Private  volatile  Status mStatus = Status.PENDING; 
     
    public  enum  Status { 
        
         * Indicates that the task has not been executed yet.
          
        PENDING, 
        
         * Indicates that the task is running.
          
        RUNNING, 
        
         * Indicates that {link AsyncTask # onPostExecute} has finished.
          
        FINISHED, 
     

     * Returns the current status of this task.
     
     *return The current status.
      
    public  Final  Status getStatus () { 
        return  mStatus; 


You can see that the initial state AsyncTask is PENDING, on behalf of a pending state, RUNNING representatives execution state, FINISHED on behalf of the end state, several states in a life cycle AsyncTask be used in many places, it is very important.
After the introduction to the outline view relevant content, then, we will from execute (Params ... params) as the entrance, the focus of analysis of the implementation process AsyncTask, we look at the code snippet execute (Params ... params) method:
     

public  Final  AsyncTask <Params, Progress, Result> execute (Params ... params) { 
        if  (mStatus! = Status.PENDING) { 
            switch  (mStatus) { 
                Case  RUNNING: 
                    // If the task is being executed is thrown 
                    // It is worth mentioning that after the call cancel canceled task, the state has not public  Final  AsyncTask <Params, Progress, Result> execute (Params ... params) { 
        if  (mStatus! = Status.PENDING) { 
            switch  (mStatus) { 
                Case  RUNNING: 
                    // If the task is being executed is thrown 
                    // It is worth mentioning that after the call cancel canceled task, the state has not yet RUNNING 
                    throw  new  IllegalStateException ( "Can not execute Task:" 
                            +  "the Task is already running." ); 
                Case  FINISHED: 
                    // If the task has finished executing exception is thrown 
                    throw  new  IllegalStateException ( "Can not execute Task:" 
                            +  "the Task has already Been Executed" 
                            +  "(a Task CAN be Executed only once)" ); 
             
         
         
        // Change status is RUNNING 
        mStatus = Status.RUNNING; 
        // Method call onPreExecute 
        onPreExecute (); 
        mWorker.mParams = params; 
        sExecutor.execute (mFuture); 
        return  this ;       


Code involves three strange variables: mWorker, sExecutor, mFuture, we will look at their true colors:
About sExecutor, it is an instance of java.util.concurrent.ThreadPoolExecutor for executive management of the thread. Code is as follows:
     
Private  static  Final  int  CORE_POOL_SIZE =  5 ; 
   Private  static  Final  int  MAXIMUM_POOL_SIZE =  128 ; 
   Private  static  Final  int  KEEP_ALIVE =  10 ; 
// Create a queue for storing threads 
   Private  static  Final  BlockingQueue <Runnable> sWorkQueue = 
           new  LinkedBlockingQueue <Runnable> ( 10 ); 
// Create a thread factory 
   Private  static  Final  ThreadFactory sThreadFactory =  new  ThreadFactory () { 
       Private  Final  AtomicInteger mCount =  new  AtomicInteger ( 1 ); 
    // Create a new thread 
       public  Thread newthread (Runnable r) { 
           return  new  Thread (r,  "AsyncTask #"  + mCount.getAndIncrement ()); 
        
    
// Create a thread pool actuator for performing management thread 
   Private  static  Final  ThreadPoolExecutor sExecutor =  new  ThreadPoolExecutor (CORE_POOL_SIZE, 
           MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sWorkQueue, sThreadFactory); 


mWorker actually implement an abstract object instance inner class AsyncTask, which implements Callable <Result> interface call () method, as follows:

Private  static  abstract  class  WorkerRunnable <Params, Result>  implements  Callable <Result> { 
        Params [] mParams;


And mFuture actually an instance java.util.concurrent.FutureTask, the following information is relevant to its FutureTask class:


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 has been cancelled.
      
    void  run (); 

You can see the class FutureTask is canceled midway for an asynchronous computation.
The following are examples of mWorker and mFuture reflected in AsyncTask in:

Private  Final  WorkerRunnable <Params, Result> mWorker; 
   Private  Final  FutureTask <Result> mFuture; 
public  AsyncTask () { 
       mWorker =  new  WorkerRunnable <Params, Result> () { 
           After // call method is called, it will set priorities for the background level, and then call the method AsyncTask of doInBackground 
        public  Result Call ()  throws  Exception { 
               Process.setThreadPriority (Process.THREAD_PRIORITY_BACKGROUND); 
               return  doInBackground (mParams); 
             
        
    // In mFuture instance, will call mWorker do background tasks, method calls done after the completion of 
       mFuture =  new  FutureTask <Result> (mWorker) { 
           Override 
           protected  void  DONE () { 
               Message message; 
               Result result =  null ; 
               try  { 
                   result = get (); 
               }  catch  (InterruptedException e) { 
                   android.util.Log.w (LOG_TAG, e); 
               }  catch  (ExecutionException e) { 
                   throw  new  RuntimeException ( "An error occured while executing doInBackground ()" , 
                           e.getCause ()); 
               }  catch  (CancellationException e) { 
                // Send the message to cancel the task 
                   message = sHandler.obtainMessage (MESSAGE_POST_CANCEL, 
                           new  AsyncTaskResult <Result> (AsyncTask. this , (Result [])  null )); 
                   message.sendToTarget (); 
                   return ; 
               }  catch  (Throwable t) { 
                   throw  new  RuntimeException ( "An error occured while executing" 
                           +  "doInBackground ()" , t); 
                
            // Display the results send a message 
               message = sHandler.obtainMessage (MESSAGE_POST_RESULT, 
                       new  AsyncTaskResult <Result> (AsyncTask. this , result)); 
               message.sendToTarget (); 
            
        
    

We see the above code, done mFuture object instance () method, if captured CancellationException type of anomaly, it sends a "MESSAGE_POST_CANCEL" message; if successfully implemented, it sends a "MESSAGE_POST_RESULT" message, and the message sHandler is associated with an object. This is actually an instance AsyncTask sHandler instance inner class InternalHandler, and it is inherited InternalHandler Handler, let's analyze its code:

Private  void  Finish (Result result) { 
        if  (isCancelled ()) result =  null ; 
        onPostExecute (result);   // display the results call onPostExecute 
        mStatus = Status.FINISHED;   // change status is FINISHED 

The original finish () method is responsible for calling onPostExecute (Result result) method to display the results and change task status ah.
In addition, done mFuture object () method to construct a message, the message contains a AsyncTaskResult type of object, and then handleMessage sHandler instances of an object (Message msg) method, the use of the following in this way obtain information that came Object:

AsyncTaskResult result = (AsyncTaskResult) msg.obj;

What exactly is this AsyncTaskResult it, what does it contain? In fact, it is an internal class AsyncTask, is used to wrap a class execution results, let us look at its structure:

// Send the message to cancel the task 
message = sHandler.obtainMessage (MESSAGE_POST_CANCEL, 
        new  AsyncTaskResult <Result> (AsyncTask. this , (Result [])  null )); 
message.sendToTarget (); 

// Display the results send a message 
message = sHandler.obtainMessage (MESSAGE_POST_RESULT, 
         new  AsyncTaskResult <Result> (AsyncTask. this , result)); 
message.sendToTarget (); 


In dealing with the message of how to use this object, let's look again:

result.mTask.finish (result.mData [ 0 ]);

result.mTask.onProgressUpdate (result.mData); 

Generally speaking, when we call the execute (Params ... params) method, execute method calls onPreExecute () method, and then perform a task by the ThreadPoolExecutor instance FutureTask sExecutor, this process doInBackground (Params ... params) will be calls, if the developer overwritten doInBackground (Params ... params) method calls publishProgress (Progress ... values) method, by InternalHandler instance sHandler send a MESSAGE_POST_PROGRESS message, update schedule, when sHandler processing messages onProgressUpdate ( Progress ... values) method is called; if you encounter an exception, it sends a message MESSAGE_POST_CANCEL, cancel the task, onCancelled () method will be called when sHandler processing the message; If successful, it sends a message MESSAGE_POST_RESULT display Results, onPostExecute (Result result) method is called when sHandler process the message.
After the above description, I believe that friends have recognized the nature of the AsyncTask, it Thread + Handler good package, reducing the complexity of the developers deal with the problem, improve the efficiency of development, I hope you can a lot of taste.

Share this

Related Posts

Previous
Next Post »