当前位置: 移动技术网 > IT编程>移动开发>Android > Android AsyncTask实现机制详细介绍及实例代码

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

2019年07月24日  | 移动技术网IT编程  | 我要评论

邯郸钢铁招聘,9c8822,鞋垫花

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

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

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网