Android中的多线程-AsyncTask源码分析
来源:互联网 发布:非织造材料与工程 知乎 编辑:程序博客网 时间:2024/05/16 05:19
/* * */public abstract class AsyncTask<Params, Progress, Result> {//Params是传入的参数,Progress用于显示进度 ,Result则为doinBackground传递给Post的参数 private static final String LOG_TAG = "AsyncTask";//线程池维护线程的最少数量 private static final int CORE_POOL_SIZE = 5;//线程池维护线程的最大数量 private static final int MAXIMUM_POOL_SIZE = 128;//线程池维护线程所允许的空闲时间 private static final int KEEP_ALIVE = 10;//线程池所使用的缓冲队列 private static final BlockingQueue<Runnable> sWorkQueue = new LinkedBlockingQueue<Runnable>(10); 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()); } };//TimeUnit.SECONDS线程池维护线程所允许的空闲时间的单位 private static final ThreadPoolExecutor sExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sWorkQueue, sThreadFactory); private static final int MESSAGE_POST_RESULT = 0x1; private static final int MESSAGE_POST_PROGRESS = 0x2; private static final int MESSAGE_POST_CANCEL = 0x3;//因为整个AsyncTask是在UI线程创建的,所以sHandler对应到UI线程Message Queue,所以可以更新UI private static final InternalHandler sHandler = new InternalHandler(); private final WorkerRunnable<Params, Result> mWorker; private final FutureTask<Result> mFuture; private volatile Status mStatus = Status.PENDING; /** * Indicates the current status of the task. Each status will be set only once * during the lifetime of a task. */ public enum Status { /** * Indicates that the task has not been executed yet. * 还没有被execute */ PENDING, /** * 运行中 * Indicates that the task is running. */ RUNNING, /** * onPostExecute 执行完毕,这些线程其实是没法终止的 * Indicates that {@link AsyncTask#onPostExecute} has finished. */ FINISHED, } /** * 异步的任务,必须是在UI线程创建 * Creates a new asynchronous task. This constructor must be invoked on the UI thread. */ public AsyncTask() {//参数和结果队,是一个runnable用来执行后台任务,调用doInBackground//WorkerRunnable是一个继承自Callable<Result>带有回调功能的类 mWorker = new WorkerRunnable<Params, Result>() { public Result call() throws Exception { Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); return doInBackground(mParams); } };//sExecutor.execute(mFuture)会先执行带有回调的mWorker,执行完毕之后会执行done()方法 mFuture = new FutureTask<Result>(mWorker) { @Override protected void done() { Message message; Result result = null; try { result = get(); } catch (InterruptedException e) {//线程被Interrupt了 android.util.Log.w(LOG_TAG, e); } catch (ExecutionException e) {//执行异常 throw new RuntimeException("An error occured while executing doInBackground()", e.getCause()); } catch (CancellationException e) {//执行cancel?通过sendToTarget message = sHandler.obtainMessage(MESSAGE_POST_CANCEL, new AsyncTaskResult<Result>(AsyncTask.this, (Result[]) null)); message.sendToTarget(); return; } catch (Throwable t) { throw new RuntimeException("An error occured while executing " + "doInBackground()", t); }//通过sendMessage和Handler配合完成doInBackground和onPostExecute的关联 message = sHandler.obtainMessage(MESSAGE_POST_RESULT, new AsyncTaskResult<Result>(AsyncTask.this, result)); message.sendToTarget(); } }; } /** * Returns the current status of this task. * * @return The current status. */ public final Status getStatus() { return mStatus; } /** * 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); /** * Runs on the UI thread before {@link #doInBackground}. * * @see #onPostExecute * @see #doInBackground */ protected void onPreExecute() { } /** * Runs on the UI thread after {@link #doInBackground}. The * specified result is the value returned by {@link #doInBackground} * or null if the task was cancelled or an exception occured. * * @param result The result of the operation computed by {@link #doInBackground}. * * @see #onPreExecute * @see #doInBackground */ @SuppressWarnings({"UnusedDeclaration"}) protected void onPostExecute(Result result) { } /** * 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) { } /** * Runs on the UI thread after {@link #cancel(boolean)} is invoked. * * @see #cancel(boolean) * @see #isCancelled() */ protected void onCancelled() { } /** * Returns <tt>true</tt> if this task was cancelled before it completed * normally. * 判断是否被cancel了 * * @return <tt>true</tt> if task was cancelled before it completed * * @see #cancel(boolean) */ public final boolean isCancelled() { return mFuture.isCancelled(); } /** * Attempts to cancel execution of this task. This attempt will * fail if the task has already completed, already been cancelled, * or could not be cancelled for some other reason. If successful, * and this task has not started when <tt>cancel</tt> is called, * this task should never run. If the task has already started, * then the <tt>mayInterruptIfRunning</tt> parameter determines * whether the thread executing this task should be interrupted in * an attempt to stop the task. * * @param mayInterruptIfRunning <tt>true</tt> if the thread executing this * task should be interrupted; otherwise, in-progress tasks are allowed * to complete. * * @return <tt>false</tt> if the task could not be cancelled, * typically because it has already completed normally; * <tt>true</tt> otherwise * * @see #isCancelled() * @see #onCancelled() */ public final boolean cancel(boolean mayInterruptIfRunning) { return mFuture.cancel(mayInterruptIfRunning); } /** * Waits if necessary for the computation to complete, and then * retrieves its result. * * @return The computed result. * * @throws CancellationException If the computation was cancelled. * @throws ExecutionException If the computation threw an exception. * @throws InterruptedException If the current thread was interrupted * while waiting. */ public final Result get() throws InterruptedException, ExecutionException { return mFuture.get(); } /** * Waits if necessary for at most the given time for the computation * to complete, and then retrieves its result. * * @param timeout Time to wait before cancelling the operation. * @param unit The time unit for the timeout. * * @return The computed result. * * @throws CancellationException If the computation was cancelled. * @throws ExecutionException If the computation threw an exception. * @throws InterruptedException If the current thread was interrupted * while waiting. * @throws TimeoutException If the wait timed out. */ public final Result get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { return mFuture.get(timeout, unit); } /** * Executes the task with the specified parameters. The task returns * itself (this) so that the caller can keep a reference to it. * * This method must be invoked on the UI thread. * * @param params The parameters of the task. * * @return This instance of AsyncTask. * * @throws IllegalStateException If {@link #getStatus()} returns either * {@link AsyncTask.Status#RUNNING} or {@link AsyncTask.Status#FINISHED}. */ public final AsyncTask<Params, Progress, Result> execute(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;//这是决定AsyncTask执行顺序逻辑的关键类,先pre,后doInBack,由back调用post onPreExecute(); mWorker.mParams = params; sExecutor.execute(mFuture); return this; } /** * This method can be invoked from {@link #doInBackground} to * publish updates on the UI thread while the background computation is * still running. Each call to this method will trigger the execution of * {@link #onProgressUpdate} on the UI thread. * * @param values The progress values to update the UI with. * * @see #onProgressUpdate * @see #doInBackground */ protected final void publishProgress(Progress... values) { sHandler.obtainMessage(MESSAGE_POST_PROGRESS, new AsyncTaskResult<Progress>(this, values)).sendToTarget(); }//这是一个私有方法,不由外部调用 private void finish(Result result) { if (isCancelled()) result = null; onPostExecute(result);//表示post方法已经执行完毕 mStatus = Status.FINISHED; }//由这个handler来处理后台runnable发送的msg private static class InternalHandler extends Handler { @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; case MESSAGE_POST_CANCEL: result.mTask.onCancelled(); break; } } }//使用的了回调,这个值得学习 private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> { Params[] mParams; }//异步任务结果类 @SuppressWarnings({"RawUseOfParameterizedType"}) private static class AsyncTaskResult<Data> { final AsyncTask mTask; final Data[] mData; AsyncTaskResult(AsyncTask task, Data... data) { mTask = task; mData = data; } }}
通过代码分析了解了AsyncTask的内部执行逻辑,接下来对于线程池和缓冲队列进行研究