声明:Android不同API版本中同一个类的实现方法可能会有不同,本文是基于最新的API 23的源码进行讲解的。
Android的UI是线程不安全的,想在子线程中更新UI就必须使用Android的异步操作机制,直接在主线程中更新UI会导致程序崩溃。
Android的异步操作主要有两种,AsyncTask和Handler。AsyncTask是一个轻量的异步类,简单、可控。本文主要结合最新的API 23的源码讲解一下AsyncTask到底是什么。
class MyAsyncTask extends AsyncTask<Void, Integer, Boolean> { @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected void onPostExecute(Boolean aBoolean) { super.onPostExecute(aBoolean); } @Override protected void onProgressUpdate(Integer... values) { super.onProgressUpdate(values); progressBar.setProgress(values[0]); } @Override protected Boolean <strong>doInBackground</strong>(Void... params) { for (int i = 0; i < 100; i++) { //调用publishProgress,触发onProgressUpdate方法 <strong>publishProgress</strong>(i); try { Thread.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); } } return true; } @Override protected void onCancelled() { super.onCancelled(); progressBar.setProgress(0); } }
startAsyncBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { myAsyncTask = new MyAsyncTask(); myAsyncTask.execute(); } });
public AsyncTask() { 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); } } }; }
public final AsyncTask<Params, Progress, Result> execute(Params... params) { return executeOnExecutor(sDefaultExecutor, params); }只有一行代码,调用了executeOnExecutor方法。
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; }
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 Handler getHandler() { synchronized (AsyncTask.class) { if (sHandler == null) { sHandler = new InternalHandler(); } return sHandler; } }
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: // There is only one result result.mTask.finish(result.mData[0]); break; case MESSAGE_POST_PROGRESS: result.mTask.onProgressUpdate(result.mData); break; } } }
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(result); } else { onPostExecute(result); } mStatus = Status.FINISHED; }如果当前任务被取消,就调用onCancelled()方法,如果没有调用onPostExecute()。