AsyncTask

301 阅读4分钟

AsyncTask使用

使用AsyncTask是在Android中实现异步任务的一种方法,所有AsyncTask都是串行执行的

/**
* Params代表:启动任务执行的输入参数
* Progress代表:后台任务执行的进度
* Result代表:后台计算结果的类型
*/
public abstract class AsyncTask<Params, Progress, Result>
/**
  * 步骤1:创建AsyncTask子类
  * 注: 
  *   a. 继承AsyncTask类
  *   b. 为3个泛型参数指定类型;若不使用,可用java.lang.Void类型代替
  *   c. 根据需求,在AsyncTask子类内实现核心方法
  */
  private class MyTask extends AsyncTask<Params, Progress, Result> {

        ....

      // 方法1:onPreExecute()
      // 作用:线程任务前的操作
      // 注:根据需求复写,在主线程执行
      @Override
      protected void onPreExecute() {
           ...
        }

      // 方法2:doInBackground()
      // 作用:接收输入参数、执行任务中的耗时操作、返回 线程任务执行的结果
      // 注:必须复写,从而自定义线程任务,在工作线程执行
      @Override
      protected String doInBackground(String... params) {

            ...// 自定义的线程任务

            // 可调用publishProgress()显示进度, 之后将执行onProgressUpdate()
             publishProgress(count);

         }

      // 方法3:onProgressUpdate()
      // 作用:显示线程任务执行的进度
      // 注:根据需求复写,在主线程执行
      @Override
      protected void onProgressUpdate(Integer... progresses) {
            ...

        }

      // 方法4:onPostExecute()
      // 作用:接收线程任务执行结果、将执行结果显示到UI组件
      // 注:必须复写,从而自定义UI操作,在主线程执行
      @Override
      protected void onPostExecute(String result) {

         ...// UI操作

        }

      // 方法5:onCancelled()
      // 作用:取消任务执行
       // 注:在主线程执行
      @Override
        protected void onCancelled() {
        ...
        }
  }

/**
  * 步骤2:创建AsyncTask子类的实例对象(即 任务实例)
  * 注:AsyncTask子类的实例必须在UI线程中创建
  */
  MyTask mTask = new MyTask();

/**
  * 步骤3:手动调用execute(Params... params) 从而执行异步线程任务
  * 注:
  *    a. 必须在UI线程中调用
  *    b. 同一个AsyncTask实例对象只能执行1次,若执行第2次将会抛出异常
  *    c. 执行任务中,系统会自动调用AsyncTask的一系列方法:onPreExecute() 、doInBackground()、onProgressUpdate() 、onPostExecute() 
  *    d. 不能手动调用上述方法
  */
  mTask.execute();

AsyncTask源码分析

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

Executor实现

// 在一个时间串行的Executor,对于特定的进程全局是串行的
public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
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);
    }
  }
}

线程池实现

// 创建线程池
static {
  ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
    CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS,
    sPoolWorkQueue, sThreadFactory);
  threadPoolExecutor.allowCoreThreadTimeOut(true);
  THREAD_POOL_EXECUTOR = threadPoolExecutor;
}

FutureTask和Callable实现

public AsyncTask() {
  this((Looper) null);
}

public AsyncTask(@Nullable Handler handler) {
  this(handler != null ? handler.getLooper() : null);
}

public AsyncTask(@Nullable Looper callbackLooper) {
  // 默认InternalHandler和主线程Looper
  mHandler = callbackLooper == null || callbackLooper == Looper.getMainLooper()
  ? getMainHandler()
  : new Handler(callbackLooper);
  // 异步任务
  mWorker = new WorkerRunnable<Params, Result>() {
    public Result call() throws Exception {
      mTaskInvoked.set(true);
      Result result = null;
      try {
        Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
        result = doInBackground(mParams);
        Binder.flushPendingCommands();
      } catch (Throwable tr) {
        mCancelled.set(true);
        throw tr;
      } finally {
        postResult(result);
      }
      return result;
    }
  };

  mFuture = new FutureTask<Result>(mWorker) {
    // 主线程回调
    @Override
    protected void done() {
      try {
        // 结果没有回调时调用,get()获取任务返回值
        postResultIfNotInvoked(get());
      } catch (InterruptedException e) {
        android.util.Log.w(LOG_TAG, e);
      } catch (ExecutionException e) {
        throw new RuntimeException("An error occurred while executing doInBackground()",
        e.getCause());
      } catch (CancellationException e) {
        postResultIfNotInvoked(null);
      }
    }
  };
}
/**
* 回调主线程
*/
private Result postResult(Result result) {
  @SuppressWarnings("unchecked")
  Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
    new AsyncTaskResult<Result>(this, result));
  message.sendToTarget();
  return result;
}

Handler实现

// 内部的Handler实现
private static class InternalHandler extends Handler {
  public InternalHandler(Looper looper) {
    super(looper);
  }
  // 主线程调用
  @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
  @Override
  public void handleMessage(Message msg) {
    AsyncTaskResult<?> result = (AsyncTaskResult<?>) msg.obj;
    switch (msg.what) {
      case MESSAGE_POST_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;
}

静态变量初始化

// 获取设备CUP的数量
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
// 我们想要至少2个线程和至多4个线程在核心线程池中,更喜欢比CUP的数量
// 少一,为了避免CPU在后台全部工作。
private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4));
// 线程池最大线程数量
private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
// 保持活着的秒数
private static final int KEEP_ALIVE_SECONDS = 30;
// 自增线程id的线程工厂
private static final ThreadFactory sThreadFactory = new ThreadFactory() {
  private final AtomicInteger mCount = new AtomicInteger(1);

  public Thread newThread(Runnable r) {
    return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());
  }
};
// 阻塞队列
private static final BlockingQueue<Runnable> sPoolWorkQueue = new LinkedBlockingQueue<Runnable>(128);
// 能并行执行任务的Executor
public static final Executor THREAD_POOL_EXECUTOR;
// 消息类型的标记
private static final int MESSAGE_POST_RESULT = 0x1;
private static final int MESSAGE_POST_PROGRESS = 0x2;
// 默认线程池
private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
private static InternalHandler sHandler;

非静态变量初始化

// FutureTask相关
private final WorkerRunnable<Params, Result> mWorker;
private final FutureTask<Result> mFuture;
private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {
  Params[] mParams;
}
// AsyncTask的状态
private volatile Status mStatus = Status.PENDING;
/**
 * 指示任务现在的状态,在任务的生命周期中,每个状态只设置一次
 */
public enum Status {
  // 指示任务还没有被执行
  PENDING,
  // 指示任务已经被执行
  RUNNING,
  // 指示任务已经完成
  FINISHED,
}

private final AtomicBoolean mCancelled = new AtomicBoolean();
private final AtomicBoolean mTaskInvoked = new AtomicBoolean();

private final Handler mHandler;

静态执行方法

/**
* 串行执行任务,无法回调主线程
*/
@MainThread
public static void execute(Runnable runnable) {
  sDefaultExecutor.execute(runnable);
}