/** * AsyncTask工作原理解析: * AsyncTask是对Handler与线程池的封装,使用它的方便之处在于能够更新用户界面 * 使用线程池的主要原因是避免不必要的创建及销毁线程的开销。 * <p> * AsyncTask的局限性: * AsyncTask对象必须在主线程中创建 * AsyncTask对象的execute方法必须在主线程中调用 * 一个AsyncTask对象只能调用一次execute方法 * <p> * 它默认使用串行方式执行任务,让它以并行的方式执行任务:queryTask.executeOnExecutor(); * * @param <Params> * @param <Progress> * @param <Result> */ public abstract class AsyncTask<Params, Progress, Result> { private static final String LOG_TAG = "AsyncTask"; //CPU核数 private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors(); //核心线程数 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; //实例化线程工厂ThreadFactory,sThreadFactory用于在后面创建线程池 private static final ThreadFactory sThreadFactory = new ThreadFactory() { //mCount为AtomicInteger类型,用AtomicInteger,它是一种线程安全的加减操作类 private final AtomicInteger mCount = new AtomicInteger(1); //重写newThread方法的目的是为了将新增线程的名字以"AsyncTask #"标识 public Thread newThread(Runnable r) { return new Thread(r, "AsyncTask #" + mCount.getAndIncrement()); } }; //实例化阻塞式队列BlockingQueue,队列中存放Runnable,容量为128 private static final BlockingQueue<Runnable> sPoolWorkQueue = new LinkedBlockingQueue<Runnable>(128); /** * 以下是是AsyncTask中定义的两个线程池,一个是SerialExecutor,另一个是THREAD_POOL_EXECUTOR。 * SerialExecutor用于串行执行任务,而THREAD_POOL_EXECUTOR才是用于并行执行任务的线程池。 */ //根据上面定义的参数实例化线程池 public static final Executor THREAD_POOL_EXECUTOR; 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; } //SerialExecutor用于串行执行任务 public static final Executor SERIAL_EXECUTOR = new SerialExecutor(); //用于通过Handler发布result的Message Code private static final int MESSAGE_POST_RESULT = 0x1; //用于通过Handler发布progress的Message Code private static final int MESSAGE_POST_PROGRESS = 0x2; /** * sDefaultExecutor表示AsyncTask默认使用SERIAL_EXECUTOR作为Executor, * 即默认情况下AsyncTask是串行执行任务,而不是并行执行任务 */ private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR; //InternalHandler是AsyncTask中定义的一个静态内部类,其绑定了主线程的Looper和消息队列 private static InternalHandler sHandler; //mWorker是一个实现了Callable接口的对象,其实现了Callable接口的call方法 private final WorkerRunnable<Params, Result> mWorker; //根据mFuture是一个FutureTask对象,需要用mWorker作为参数实例化mFuture private final FutureTask<Result> mFuture; //AsyncTask的初始状态位PENDING private volatile Status mStatus = Status.PENDING; //mCancelled标识当前任务是否被取消了 private final AtomicBoolean mCancelled = new AtomicBoolean(); //mTaskInvoked标识当前任务是否真正开始执行了 private final AtomicBoolean mTaskInvoked = new AtomicBoolean(); private final Handler mHandler; /** * SerialExecutor实现了Executor接口中的execute方法,该类用于串行执行任务, * 即一个接一个地执行任务,而不是并行执行任务 */ private static class SerialExecutor implements Executor { //mTasks是一个维护Runnable的双端队列,ArrayDeque没有容量限制,其容量可自增长 final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>(); //mActive表示当前正在执行的任务Runnable Runnable mActive; public synchronized void execute(final Runnable r) { //execute方法会传入一个Runnable类型的变量r //然后我们会实例化一个Runnable类型的匿名内部类以对r进行封装, //通过队列的offer方法将封装后的Runnable添加到队尾 mTasks.offer(new Runnable() { public void run() { try { //执行r的run方法,开始执行任务 //此处r的run方法是在线程池中执行的 r.run(); } finally { //当任务执行完毕的时候,通过调用scheduleNext方法执行下一个Runnable任务 scheduleNext(); } } }); //只有当前没有执行任何任务时,才会立即执行scheduleNext方法 if (mActive == null) { scheduleNext(); } } /** * 执行下一个Runnable任务 */ protected synchronized void scheduleNext() { //通过mTasks的poll方法进行出队操作,删除并返回队头的Runnable, //将返回的Runnable赋值给mActive, //如果不为空,那么就让将其作为参数传递给THREAD_POOL_EXECUTOR的execute方法进行执行 if ((mActive = mTasks.poll()) != null) { THREAD_POOL_EXECUTOR.execute(mActive); } } } /** * AsyncTask内部定义了一个Status枚举类型 * 一个AsyncTask正常情况下会经历PENDING->RUNNING->FINISHED三个状态。 */ public enum Status { /** * 表示还没有开始执行任务 */ PENDING, /** * 表示已经开始执行任务 */ RUNNING, /** * 示任务已经执行完成或被取消了,总之onPostExecute方法已经被调用了 */ FINISHED, } private static Handler getMainHandler() { synchronized (AsyncTask.class) { if (sHandler == null) { sHandler = new InternalHandler(Looper.getMainLooper()); } return sHandler; } } private Handler getHandler() { return mHandler; } public static void setDefaultExecutor(Executor exec) { sDefaultExecutor = exec; } /** * 构造函数:创建一个新的异步任务,必须在UI线程上调用此构造函数。 */ public AsyncTask() { this((Looper) null); } /** * 构造函数:创建一个新的异步任务,必须在UI线程上调用此构造函数。 * * @hide */ public AsyncTask(@Nullable Handler handler) { this(handler != null ? handler.getLooper() : null); } /** * 构造函数:创建一个新的异步任务,必须在UI线程上调用此构造函数。 * * @hide */ public AsyncTask(@Nullable Looper callbackLooper) { mHandler = callbackLooper == null || callbackLooper == Looper.getMainLooper() ? getMainHandler() : new Handler(callbackLooper); //实例化mWorker,实现了Callable接口的call方法 mWorker = new WorkerRunnable<Params, Result>() { public Result call() throws Exception { //call方法是在线程池的某个线程中执行的,而不是运行在主线程中 //call方法开始执行后,就将mTaskInvoked设置为true,表示任务开始执行 mTaskInvoked.set(true); Result result = null; try { //将执行call方法的线程设置为后台线程级别 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); //在线程池的工作线程中执行doInBackground方法,执行实际的任务,并返回结果 result = doInBackground(mParams); Binder.flushPendingCommands(); } catch (Throwable tr) { mCancelled.set(true); throw tr; } finally { //将执行完的结果传递给postResult方法 postResult(result); } return result; } }; //用mWorker实例化mFuture mFuture = new FutureTask<Result>(mWorker) { @Override protected void done() { //任务执行完毕或取消任务都会执行done方法 try { 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 void postResultIfNotInvoked(Result result) { final boolean wasTaskInvoked = mTaskInvoked.get(); if (!wasTaskInvoked) { postResult(result); } } private Result postResult(Result result) { //通过getHandler获取InternalHandler,InternalHandler绑定主线程 //根据InternalHandler创建一个Message Code为MESSAGE_POST_RESULT的Message Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT, new AsyncTaskResult<Result>(this, result)); //将该message发送给InternalHandler message.sendToTarget(); return result; } /** * Returns the current status of this task. * * @return The current status. */ public final Status getStatus() { return mStatus; } @WorkerThread protected abstract Result doInBackground(Params... params); @MainThread protected void onPreExecute() { } @SuppressWarnings({"UnusedDeclaration"}) @MainThread protected void onPostExecute(Result result) { } @SuppressWarnings({"UnusedDeclaration"}) @MainThread protected void onProgressUpdate(Progress... values) { } @SuppressWarnings({"UnusedParameters"}) @MainThread protected void onCancelled(Result result) { onCancelled(); } @MainThread protected void onCancelled() { } public final boolean isCancelled() { return mCancelled.get(); } public final boolean cancel(boolean mayInterruptIfRunning) { mCancelled.set(true); return mFuture.cancel(mayInterruptIfRunning); } public final Result get() throws InterruptedException, ExecutionException { return mFuture.get(); } public final Result get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { return mFuture.get(timeout, unit); } /** * 在实例化了AsyncTask对象之后,我们就可以调用AsyncTask的execute方法执行任务 * * @param params * @return */ @MainThread public final AsyncTask<Params, Progress, Result> execute(Params... params) { return executeOnExecutor(sDefaultExecutor, params); } @MainThread public static void execute(Runnable runnable) { sDefaultExecutor.execute(runnable); } /** * 一个AsyncTask实例执行执行一次任务,当第二次执行任务时就会抛出异常。executeOnExecutor方法一开始就检查 * AsyncTask的状态是不是PENDING,只有PENDING状态才往下执行,如果是其他状态表明现在正在执行另一个已有的 * 任务或者已经执行完成了一个任务,这种情况下都会抛出异常。 * * @param exec * @param params * @return */ @MainThread public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec, Params... params) { if (mStatus != Status.PENDING) { switch (mStatus) { case RUNNING: //如果当前AsyncTask已经处于运行状态,那么就抛出异常,不再执行新的任务 throw new IllegalStateException("Cannot execute task:" + " the task is already running."); case FINISHED: //如果当前AsyncTask已经把之前的任务运行完成,那么也抛出异常,不再执行新的任务 throw new IllegalStateException("Cannot execute task:" + " the task has already been executed " + "(a task can be executed only once)"); } } /** * 如果开始是PENDING状态,那么就说明该AsyncTask还没执行过任何任务,代码可以继续执行, * 然后将状态设置为RUNNING,表示开始执行任务。 */ //将AsyncTask的状态置为运行状态 mStatus = Status.RUNNING; //在真正执行任务前,先调用onPreExecute方法 onPreExecute(); mWorker.mParams = params; //Executor的execute方法接收Runnable参数,由于mFuture是FutureTask的实例, //且FutureTask同时实现了Callable和Runnable接口,所以此处可以让exec执行mFuture exec.execute(mFuture); //最后将AsyncTask自身返回 return this; } /** * doInBackground方法是在工作线程中执行比较耗时的操作,这个操作时间可能比较长,而我们的任务有可能分成 * 多个部分,每当我完成其中的一部分任务时,我们可以在doInBackground中多次调用AsyncTask * 的publishProgress方法,将阶段性数据发布出去。 * * @param values */ @WorkerThread protected final void publishProgress(Progress... values) { if (!isCancelled()) { getHandler().obtainMessage(MESSAGE_POST_PROGRESS, new AsyncTaskResult<Progress>(this, values)).sendToTarget(); } } private void finish(Result result) { if (isCancelled()) { //如果任务被取消了,那么执行onCancelled方法 onCancelled(result); } else { //将结果发传递给onPostExecute方法 onPostExecute(result); } //最后将AsyncTask的状态设置为完成状态 mStatus = Status.FINISHED; } /** * InternalHandler是AsyncTask中定义的一个静态内部类,其绑定了主线程的Looper和消息队列 */ 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 static abstract class WorkerRunnable<Params, Result> implements Callable<Result> { Params[] mParams; } /** * AsyncTask的一个内部类 * * @param <Data> */ private static class AsyncTaskResult<Data> { //mTask表示当前AsyncTaskResult是哪个AsyncTask的结果 final AsyncTask mTask; //mData表示其存储的数据 final Data[] mData; AsyncTaskResult(AsyncTask task, Data... data) { //此处的data是可变数组 mTask = task; mData = data; } } }
AsyncTask(项目总结)
最新推荐文章于 2022-07-03 13:47:54 发布