Android thread (2) AsyncTask (1)

Source: Internet
Author: User

Android thread (2) AsyncTask (1)

 

The basic usage of AsyncTask is not described here. It is an android developer.

1. AsyncTask before android 3.0

private static final int CORE_POOL_SIZE = 5;  private static final int MAXIMUM_POOL_SIZE = 128;  private static final it KEEP_ALIVE = 10;  ……  private static final ThreadPoolExecutor sExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE,          MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sWorkQueue, sThreadFactory);  

Here we can see ThreadPoolExecutor. I have introduced the principle of ThreadPoolExecutor in the previous article: http://blog.csdn.net/itachi85/article/details/43794511.

Five threads can be run at the same time, and the total thread pool size is 128. When the number of threads exceeds the core, the maximum waiting time of redundant Idle threads before the termination of a new task is 10 seconds. For AsyncTask before 3.0, five tasks can be executed simultaneously, while for AsyncTask after 3.0, only one task can be executed simultaneously.

2. Let's take a look at the AsyncTask of android 4.3.

AsyncTask constructor:

 /**     * Creates a new asynchronous task. This constructor must be invoked on the UI thread.     */    public AsyncTask() {        mWorker = new WorkerRunnable
 
  () {            public Result call() throws Exception {                mTaskInvoked.set(true);                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);                //noinspection unchecked                return postResult(doInBackground(mParams));            }        };        mFuture = new FutureTask
  
   (mWorker) {            @Override            protected void done() {                try {                    postResultIfNotInvoked(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) {                    postResultIfNotInvoked(null);                }            }        };    }
  
 

This code initializes two variables, mWorker and mFuture. When initializing mFuture, mWorker is passed in as a parameter. MWorker is a Callable object, and mFuture is a FutureTask object. These two variables are temporarily stored in the memory and will be used later.

When we use AsyncTask, most of the time we call the execute () method to see the source code of execute:

 

    public final AsyncTask
 
   execute(Params... params) {        return executeOnExecutor(sDefaultExecutor, params);}
 

 

 

 

Returned executeOnExecutor and passed it to sDefaultExecutor (default thread pool ). First look at the executeOnExecutor source code:

 

 public final AsyncTask
 
   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;    }
 

 

 

 

 

 

 

 

 

 

 

The passed thread pool exec calls the execute method and passes the mFuture mentioned above.

The passed thread pool sDefaultExecutor is the default thread pool SerialExecutor, that is, the execute () method of SerialExecutor is called:

 

  public static final Executor SERIAL_EXECUTOR = new SerialExecutor();  private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;

 

 

 

 

Source code of SerialExecutor:

        private static class SerialExecutor implements Executor {        final ArrayDeque
 
   mTasks = new ArrayDeque
  
   ();        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);            }        }    }
  
 

 

Call the execute method of SerialExecutor. here we can see that a Runnable is passed in. This Runnable is the mFuture (FutureTask) mentioned above, and the run method of FutureTask is executed in the ninth line:

 

 public void run() {        if (state != NEW ||            !UNSAFE.compareAndSwapObject(this, runnerOffset,                                         null, Thread.currentThread()))            return;        try {            Callable
 
   c = callable;            if (c != null && state == NEW) {                V result;                boolean ran;                try {                    result = c.call();                    ran = true;                } catch (Throwable ex) {                    result = null;                    ran = false;                    setException(ex);                }                if (ran)                    set(result);            }        } finally {            // runner must be non-null until state is settled to            // prevent concurrent calls to run()            runner = null;            // state must be re-read after nulling runner to prevent            // leaked interrupts            int s = state;            if (s >= INTERRUPTING)                handlePossibleCancellationInterrupt(s);        }    }
 

 

 

 

 

 

 

 

 

 

C. call is executed in the run method. Here c is the mWorker (WorkerRunnable) we mentioned above ). Run the call method of WorkerRunnable:

 

 

 mWorker = new WorkerRunnable
 
  () {            public Result call() throws Exception {                mTaskInvoked.set(true);                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);                //noinspection unchecked                return postResult(doInBackground(mParams));            }
 


Source code of the last postResult () method:

 

 private Result postResult(Result result) {        @SuppressWarnings(unchecked)        Message message = sHandler.obtainMessage(MESSAGE_POST_RESULT,                new AsyncTaskResult
 
  (this, result));        message.sendToTarget();        return result;    }
 

 

 

 

 

 

 

We found that a message is sent, and the message sent by the above Code is accepted here:

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 is only one result                    result.mTask.finish(result.mData[0]);                    break;                case MESSAGE_POST_PROGRESS:                    result.mTask.onProgressUpdate(result.mData);                    break;            }        }    }


The message is MESSAGE_POST_RESULT, so result. mTask. finish (result. mData [0]) will be executed. finish source code:

 

  private void finish(Result result) {        if (isCancelled()) {            onCancelled(result);        } else {            onPostExecute(result);        }        mStatus = Status.FINISHED;    }

 

 

 

 

 

 

 

When canceled, onCancelled (result) is executed; otherwise, onPostExecute (result) is called ); in this way, we can get the result we need in onPostExecute to proceed to the next step.

 

 

 

 

 


 

?? ?? ?? ?? ?? ?? ?? ?? ?? ??

Related Article

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.