欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android AsyncTask实现机制详细介绍及实例代码

程序员文章站 2024-02-24 08:49:06
android asynctask实现机制 示例代码: public final asynctask

android asynctask实现机制

示例代码:

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:"
              + " 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;
  }

execute先调用onpreexecute()(可见,onpreexecute是自动调用的)然后调用exec.execute(mfuture)

 public interface executor {
    void execute(runnable command);
  }

这是一个接口,具体实现在

 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);
      }
    }
  }

从上面可知,asynctask执行过程如下:先执行onpreexecute,然后交给serialexecutor执行。在serialexecutor中,先把runnable添加到mtasks中。

如果没有runnable正在执行,那么就调用serialexecutor的schedulenext。同时当一个runnable执行完以后,继续执行下一个任务

asynctask中有两个线程池,thread_pool_executor和serial_executor,以及一个handler–internalhandler

 /**
   * an {@link executor} that can be used to execute tasks in parallel.
   */
  public static final executor thread_pool_executor
      = new threadpoolexecutor(core_pool_size, maximum_pool_size, keep_alive,
          timeunit.seconds, spoolworkqueue, sthreadfactory);

  /**
   * an {@link executor} that executes tasks one at a time in serial
   * order. this serialization is global to a particular process.
   */
  public static final executor serial_executor = new serialexecutor();

  private static internalhandler shandler;

serial_executor用于任务的排列,thread_pool_executor真正执行线程,internalhandler用于线程切换
先看构造函数

  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());
        } catch (cancellationexception e) {
          postresultifnotinvoked(null);
        }
      }
    };
  }

看到了熟悉的doinbackground了吧,然后调用postresult

 private result postresult(result result) {
    @suppresswarnings("unchecked")
    message message = gethandler().obtainmessage(message_post_result,
        new asynctaskresult<result>(this, result));
    message.sendtotarget();
    return result;
  }

主线程中创建internalhandler并发送message_post_result消息,然后调用finish函数

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

  private void finish(result result) {
    if (iscancelled()) {
      oncancelled(result);
    } else {
      onpostexecute(result);
    }
    mstatus = status.finished;
  }

finish中调用onpostexecute。

asynctask工作流程:new mythread().execute(1);

先构造函数,然后execute

构造函数只是准备了mworker和mfuture这两个变量

execute中调用onpreexecute,然后exec.execute(mfuture),其中响应了call函数,call中调用doinbackground,然后将结果传给handler然后finish掉,finish函数调用onpostexecute

你可能会奇怪,为什么没有onprogressupdate,有注解可以解释

 /**
   * 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) {
  }

也就是说必须调用publishprogress才会自动调用onprogressupdate。
那如何调用publishprogress呢?

 /**
   * override this method 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说的很明确,在doinbackground函数里面显示调用publishprogress即可。

publishprogress源码:

 protected final void publishprogress(progress... values) {
    if (!iscancelled()) {
      gethandler().obtainmessage(message_post_progress,
          new asynctaskresult<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) {
        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;
      }
    }
  }

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!