class MyAsyncTask extends AsyncTask<Integer, Integer, Integer> { @Override protected void onPreExecute() { super.onPreExecute(); Log.i(TAG, "onPreExecute...(開始執行後臺任務以前)"); } @Override protected void onPostExecute(Integer i) { super.onPostExecute(i); Log.i("TAG", "onPostExecute...(開始執行後臺任務以後)"); } @Override protected Integer doInBackground(Integer... params) { Log.i(TAG, "doInBackground...(開始執行後臺任務)"); return 0; } }
new MyAsyncTask().execute();
//建立一個新的異步任務。必須在UI線程上調用此構造函數 public AsyncTask() { this((Looper) null); } //建立一個新的異步任務。必須在UI線程上調用此構造函數 public AsyncTask(@Nullable Handler handler) { this(handler != null ? handler.getLooper() : null); } public AsyncTask(@Nullable Looper callbackLooper) { 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); //noinspection unchecked 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 { 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); } } }; }
看一下execute方法php
@MainThread
public final AsyncTask<Params, Progress, Result> execute(Params... params) { return executeOnExecutor(sDefaultExecutor, params); }
若是execute方法不是運行在主線程中會出現什麼狀況呢?java
new Thread(new Runnable() { @Override public void run() { Log.i("tag", Thread.currentThread().getId() + ""); new MAsyncTask().execute(); } }).start(); Log.i("tag", "mainThread:" + Thread.currentThread().getId() + ""); @Override protected void onPreExecute() { super.onPreExecute(); //更新UI title.setText("瀟湘劍雨"); Log.i(TAG, "onPreExecute...(開始執行後臺任務以前)"); }
Process: com.example.aaron.helloworld, PID: 659 android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
接着看看executeOnExecutor這個方法源碼android
而後將execute方法的參數賦值給mWorker對象那個,最後執行exec.execute(mFuture)方法,並返回自身。git
模擬測試一下拋出異常的操做github
final MyAsyncTask mAsyncTask = new MyAsyncTask(); title.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { new Thread(new Runnable() { @Override public void run() { Log.i("tag", Thread.currentThread().getId() + ""); mAsyncTask.execute(); } }).start(); Log.i("tag", "mainThread:" + Thread.currentThread().getId() + ""); } });
Cannot execute task:the task is already running.
Cannot execute task:the task has already been executed (a task can be executed only once)
而後看一下exec.execute(mFuture)的實現面試
private static volatile Executor sDefaultExecutor = SERIAL_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); } } }
mWorker = new WorkerRunnable<Params, Result>() { public Result call() throws Exception { mTaskInvoked.set(true); Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); //noinspection unchecked Result result = doInBackground(mParams); Binder.flushPendingCommands(); return postResult(result); } };
mFuture = new FutureTask<Result>(mWorker) { @Override protected void 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) { @SuppressWarnings("unchecked") Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT, new AsyncTaskResult<Result>(this, result)); message.sendToTarget(); return result; }
private static class InternalHandler extends Handler { public InternalHandler() { super(Looper.getMainLooper()); } @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; }
private Result postResult(Result result) { @SuppressWarnings("unchecked") Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT, new AsyncTaskResult<Result>(this, result)); message.sendToTarget(); return result; }
@Override protected ReusableBitmap doInBackground(Void... params) { // enqueue the 'onDecodeBegin' signal on the main thread publishProgress(); return decode(); } @WorkerThread protected final void publishProgress(Progress... values) { if (!isCancelled()) { getHandler().obtainMessage(MESSAGE_POST_PROGRESS, new AsyncTaskResult<Progress>(this, values)).sendToTarget(); } }