美文网首页
AsyncTask的一些疑问

AsyncTask的一些疑问

作者: BlackNeko | 来源:发表于2017-01-22 22:17 被阅读101次

使用:新建类继承AsyncTask,实现其doInBackground方法

protected void onPreExecute()
protected String doInBackground(String... params)
protected void onProgressUpdate(Integer... values)
protected void onCancelled()
protected void onCancelled(String s)
protected void onPostExecute(String s)

或者直接new

AsyncTask<String, Integer, String> asyncTask
                = new AsyncTask<String, Integer, String>() {
    @Override
    protected String doInBackground(String... params) {
        return null;
    }
};
asyncTask.execute("hii");

doInBackground(String... params) 中要更新UI可以调用 publishProgress(Progress... values) , publishProgress() 方法本身执行在异步线程,但会调用 Handler 发 MESSAGE_POST_PROGRESS事件抛到主线程,让 onProgressUpdate(Integer... values) 处理,不要手动调用 onProgressUpdate(Integer... values)

为什么只能在UI线程创建?

因为Android老的版本上用于线程间通信的 InternalHandler 创建时没有为其指定Looper,所以它会默认使用当前线程的Looper,如果当前线程没有事先调用过 Looper.prepare() ,就会报 RuntimeException("Can't create handler inside thread that has not called Looper.prepare()") 异常,即使调用过 Looper.prepare() 由于不是主线程,也不能去修改UI。至少在API 16上是这样,后来的版本里面这条被修改了,AsyncTask 在实例化 InternalHandler 是为其指定主线程。

public InternalHandler() {
    super(Looper.getMainLooper());
}

为什么只能在主线程中调用 AsyncTask#execute() ?

先看执行代码:

@MainThread
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
    return executeOnExecutor(sDefaultExecutor, params);
}

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

并没有为 onPreExecute() 方法的执行特别指定线程,所以 onPreExecute() 是执行在当前线程,如果要在 onPreExecute() 中修改UI的话,AsyncTask#execute() 就要在UI线程中执行。

为什么一个AsyncTask实例只能执行一次?

在并发条件下多次执行execute(),会让线程内的数据不安全,并没有加锁机制,而是限制一个Task只能被执行一次。

其他

仿 AsyncTask 做的一个单线程执行工具(从《Android开发进阶》这本书上看到的)

DbCommand.java

可以改单线程为多个线程:

private static int coreThreadNum = Runtime.getRuntime().availableProcessors();
private final static ExecutorService executor = new ThreadPoolExecutor(
         coreThreadNum, coreThreadNum, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());

相关文章

  • AsyncTask的一些疑问

    使用:新建类继承AsyncTask,实现其doInBackground方法 或者直接new 在 doInBackg...

  • 基础疑问:AsyncTask

    AsyncTask用于什么场景? 提供了一种简洁的方式去处理异步任务。因为代码很集中。不像handler那样分散。...

  • AsyncTask学习笔记

    AsyncTask的基本使用 步骤: 继承AsyncTask 重写onPreExecute() 用来做一些初始准...

  • 详细解读AsyncTask的黑暗面以及一种替代方案

    基于最新版本的AsyncTask详细解读主要是一些AsyncTask的原理解读,本篇将分析AsyncTask使用的...

  • Android AsyncTask 详解

    Android AsyncTask 详解 内容划分 AsyncTask简介 简单使用 繁杂部分和源码浅析 一些坑的...

  • Android-AsyncTask异步任务

    AsyncTask介绍Android的AsyncTask比Handler更轻量级一些,适用于简单的异步处理。首先明...

  • 简述AsyncTask

    AsyncTask是什么? AsyncTask是Google提供的一个轻量级的异步任务类,它可以在线程池中执行一些...

  • AsyncTask详解

    AsyncTask的使用大家应该都不陌生,内部原理就是线程池与Handler的运用。简单的使用 现在有个疑问是 怎...

  • AsyncTask使用介绍

    AsyncTask介绍 AsyncTask可以用来处理一些后台较耗时的任务,查看源码发现其内部就是一个Handle...

  • Android 多线程和线程池详解

    AsyncTask 使用 AsyncTask 需要继承 AsyncTask,重写 doInBackground 方...

网友评论

      本文标题: AsyncTask的一些疑问

      本文链接:https://www.haomeiwen.com/subject/spwobttx.html