Android Asynctask Implementation mechanism detailed introduction and instance code _android

Source: Internet
Author: User
Tags static class

Android Asynctask Implementation Mechanism

Sample code:

Public final Asynctask<params, Progress, result> execute (Params ... Params) {return
    executeonexecutor ( Sdefaultexecutor, params);

  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:"
              + "task is already running. ");
        Case finished:
          throw new IllegalStateException ("Cannot execute task:
              +" The task has already been "executed" 15/>+ "(a task can be executed only once)");
      }

    Mstatus = status.running;

    OnPreExecute ();

    Mworker.mparams = params;
    Exec.execute (mfuture);

    return this;
  }

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

 Public interface Executor {
    void execute (Runnable command);
  }

This is an interface, specifically implemented in

 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 { C11/>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, asynctask execution process is as follows: First execute onpreexecute, then give serialexecutor execution. In the Serialexecutor, add the runnable to the Mtasks first.

If no runnable is executing, then the Serialexecutor Schedulenext is invoked. At the same time, when a runnable is finished, proceed to the next task

The asynctask has two thread pools, Thread_pool_executor and Serial_executor, and a Handler–internalhandler

 /**
   * A {@link Executor} that can is used to execute the tasks in parallel.
   * * Public
  static final Executor thread_pool_executor
      = new Threadpoolexecutor (core_pool_size, Maximum_pool_ SIZE, Keep_alive,
          timeunit.seconds, Spoolworkqueue, sthreadfactory);

  /**
   * A {@link Executor} that executes tasks one at the time of serial
   * order. This serialization are global to a particular process.
   * * Public
  static final Executor serial_executor = new Serialexecutor ();

  private static Internalhandler Shandler;

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

  Public Asynctask () {
    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));
      }
    ;

    Mfuture = new Futuretask<result> (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 ());
        Cancellationexception e) {
          postresultifnotinvoked (null);}}
    ;
  }

See the familiar doinbackground, and then call Postresult

 Private result Postresult {
    @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 msg) {
      asynctaskresult<?> result = (asynctaskresult<?>) msg.obj;
      Switch (msg.what) {case
        Message_post_result:
          //There be only one result
          result.mTask.finish ( Result.mdata[0]);
          break;
        Case message_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);

Constructor first, then execute

Constructor just prepares the two variables mworker and mfuture

In Execute, call OnPreExecute, then Exec.execute (mfuture), which responds to the call function, calls Doinbackground, and then passes the result to handler and then finish, Finish function Call OnPostExecute

You may wonder why there is no onprogressupdate, and there are annotations that can 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"})
  protected void Onprogressupdate (Progress ... values) {
  }

This means that publishprogress must be invoked to automatically invoke Onprogressupdate.
So how do you call publishprogress?

 /**
   * Override to perform a computation on a background thread. The
   * Specified parameters are the parameters passed to {@link #execute} * By the caller of this
   task.
   * This method
   can call {@link #publishProgress} to publish updates * on the
   UI thread.
   *
   * @param params the parameters of the task.
   *
   @return A result, defined by the subclass of this task.
   * *
   @see #onPreExecute ()
   * @see #onPostExecute
   * @see #publishProgress
   /
  protected abstract Result Doinbackground (Params ... Params);

Doinbackground said very clearly, in the Doinbackground function inside the display call publishprogress can.

Publishprogress Source:

 protected final void publishprogress (Progress ... values) {if (!iscancelled ()) { GetHandler (). Obtainmessage (Message_post_progress, New asynctaskresult<progress> (this, values)). SendToT
    Arget (); } private static Class Internalhandler extends Handler {public Internalhandler () {Super (LOOPER.GETMAINL
    Ooper ()); @SuppressWarnings ({"Unchecked", "Rawuseofparameterizedtype"}) @Override public void Handlemessage (Message m
      SG) {asynctaskresult<?> result = (asynctaskresult<?>) msg.obj; Switch (msg.what) {case Message_post_result://There be only one result Result.mTask.finish (
          Result.mdata[0]);
        Break Case Message_post_progress://**************************************** here to call RESULT.MTASK.ONPROGRESSUPD
          Ate (Result.mdata);
      Break }
    }
  }

Thank you for reading, I hope to help you, thank you for your support for this site!

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.