privateclassDownloadFilesTaskextendsAsyncTask<URL, Integer, Long> { protected Long doInBackground(URL... urls){ int count = urls.length; long totalSize = 0; for (int i = 0; i < count; i++) { totalSize += Downloader.downloadFile(urls[i]); publishProgress((int) ((i / (float) count) * 100)); // Escape early if cancel() is called if (isCancelled()) break; } return totalSize; }
privatestatic InternalHandler sHandler; /** * Creates a new asynchronous task. This constructor must be invoked on the UI thread. */ publicAsyncTask(){ mWorker = new WorkerRunnable<Params, Result>() { public Result call()throws Exception { //mTaskInvoked是一个AtomicBoolean变量,设置为true表明task正在执行 mTaskInvoked.set(true); //线程优先级设置为后台 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); //noinspection unchecked Result result = doInBackground(mParams); Binder.flushPendingCommands(); return postResult(result); } };
/** * An {@link Executor} that can be used to execute tasks in parallel. */ publicstaticfinal 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. * 串行池,UI线程,对应之前讲到的 AsyncTask 类必须在 UI 线程中加载 */ publicstaticfinal Executor SERIAL_EXECUTOR = new SerialExecutor(); privatestaticvolatile Executor sDefaultExecutor = SERIAL_EXECUTOR; privatestaticclassSerialExecutorimplementsExecutor{ //队列 final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>(); //当前执行的Runnable Runnable mActive;
protectedsynchronizedvoidscheduleNext(){ //出队列,将值传递给mActive if ((mActive = mTasks.poll()) != null) { THREAD_POOL_EXECUTOR.execute(mActive); } } } @MainThread publicfinal AsyncTask<Params, Progress, Result> execute(Params... params) { return executeOnExecutor(sDefaultExecutor, params); } @MainThread publicfinal AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec, Params... params) { //这里就是之前介绍说到的,一个task只能被执行一次 if (mStatus != Status.PENDING) { switch (mStatus) { case RUNNING: thrownew IllegalStateException("Cannot execute task:" + " the task is already running."); case FINISHED: thrownew IllegalStateException("Cannot execute task:" + " the task has already been executed " + "(a task can be executed only once)"); } } //将状态改为RUNNING mStatus = Status.RUNNING; //调用onPreExecute onPreExecute(); //将参数传递给mWorker mWorker.mParams = params; //执行 exec.execute(mFuture);
returnthis; } /** * Indicates the current status of the task. Each status will be set only once * during the lifetime of a task. */ publicenum Status { /** * Indicates that the task has not been executed yet. * 表示task还没有被执行 */ PENDING, /** * Indicates that the task is running. * 表示task正在运行 */ RUNNING, /** * Indicates that {@link AsyncTask#onPostExecute} has finished. * 表示task已经运行完了 */ FINISHED, } }
publicabstractclassAsyncTask<Params, Progress, Result> { @WorkerThread protectedfinalvoidpublishProgress(Progress... values){ if (!isCancelled()) { getHandler().obtainMessage(MESSAGE_POST_PROGRESS, new AsyncTaskResult<Progress>(this, values)).sendToTarget(); } } privatestaticclassInternalHandlerextendsHandler{ publicInternalHandler(){ super(Looper.getMainLooper()); }
@SuppressWarnings({"unchecked", "RawUseOfParameterizedType"}) @Override publicvoidhandleMessage(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; } } } }
publicabstractclassAsyncTask<Params, Progress, Result> { @MainThread publicfinal AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec, Params... params) { if (mStatus != Status.PENDING) { switch (mStatus) { case RUNNING: thrownew IllegalStateException("Cannot execute task:" + " the task is already running."); case FINISHED: thrownew 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);
returnthis; } }
executeOnExecutor 该方法之前分析过,但是需要注意的是该方法是 public ,所以用户可以传入自己的线程池。
1 2
Executor exec = new ThreadPoolExecutor(15, 200, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>()); new DownloadTask().executeOnExecutor(exec);
support V4 中有一个 AsyncTask 的兼容类 AsyncTaskCompat 。主要逻辑就是在 API 11 之前并行处理 Task,而 API 11 之后也改为并行处理 Task 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
publicclassAsyncTaskCompat{ publicstatic <Params, Progress, Result> AsyncTask<Params, Progress, Result> executeParallel( AsyncTask<Params, Progress, Result> task, Params... params) { if (task == null) { thrownew IllegalArgumentException("task can not be null"); }
if (Build.VERSION.SDK_INT >= 11) { // From API 11 onwards, we need to manually select the THREAD_POOL_EXECUTOR AsyncTaskCompatHoneycomb.executeParallel(task, params); } else { // Before API 11, all tasks were run in parallel task.execute(params); }