Android查缺补漏(线程篇)-- AsyncTask的使用及原理详细分析 (4)

WorkerRunnable的call方法中的代码很好理解,首先调用了mTaskInvoked.set(true),将任务的设为已调用状态。接着调用了doInBackground方法并获取了返回值,然后将返回值传递给postResult()方法,再看postResult方法的源码如下:

private Result postResult(Result result) { @SuppressWarnings("unchecked") Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT, new AsyncTaskResult<Result>(this, result));// 在这里将doInBackground的返回结果result封装到AsyncTaskReuslt对象里面通过handler发送给主线程 message.sendToTarget(); return result; }

在此方法中通过handler发送了一条MESSAGE_POST_RESULT的消息。此handler的相关代码如下(为方便查看,适当调整了代码顺序):

private final Handler mHandler; private Handler getHandler() { return mHandler; } /** * Creates a new asynchronous task. This constructor must be invoked on the UI thread. */ public AsyncTask() { this((Looper) null); // 在这里传入了null } /** * Creates a new asynchronous task. This constructor must be invoked on the UI thread. * * @hide */ public AsyncTask(@Nullable Handler handler) { this(handler != null ? handler.getLooper() : null); // 根据上一步调用可知,handler为null } /** * Creates a new asynchronous task. This constructor must be invoked on the UI thread. * * @hide */ public AsyncTask(@Nullable Looper callbackLooper) { mHandler = callbackLooper == null || callbackLooper == Looper.getMainLooper() ? getMainHandler() // 根据上一步调用可知,callbackLooper为null,在此会调用getMainHandler() : new Handler(callbackLooper); ... } private static Handler getMainHandler() { synchronized (AsyncTask.class) { if (sHandler == null) { sHandler = new InternalHandler(Looper.getMainLooper()); } return sHandler; } } private static InternalHandler sHandler;

在上面的源码中可知,最终getHandler()方法最终是为sHandler,而sHandler是一个静态的Handler对象,sHandler的作用是将执行环境切换到主线程中,所以这就要求sHandler要在主线程中被初始化,而由于静态成员会在类加载时被初始化,这就又要求了AsyncTask类必须在主线程中加载,否则该进程中的AsyncTask任务都无法正常工作。InternalHandler相关的源码如下:

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: // (看这里) // There is only one result result.mTask.finish(result.mData[0]); // 调用AsyncTask的finish方法。 break; ... } } } private void finish(Result result) { if (isCancelled()) { onCancelled(result); // 如果任务被取消了就去调用onCancelled方法。 } else { onPostExecute(result); // 任务完成后就将执行结果传递给onPostExecute方法 } mStatus = Status.FINISHED; // 最后将状态置为FINISHED }

7、接着再来看一下第五步中的FutureTask的源码

mFuture = new FutureTask<Result>(mWorker) { @Override protected void done() { // 1、在执行完mWorker的call方法之后会执行done方法。2、或者在FutureTask任务被取消后也会执行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); // 在Future任务被取消时,在此段代码中就会抛出CancellationException异常,即会执行此方法。 } } };

我们知道Future被执行后,会调用传入的mWorker的call方法,在执行完mWorker的call方法之后或者FutureTask被取消时会调用done方法,我们看到源码中在done方法中调用postResultIfNotInvoked():

private void postResultIfNotInvoked(Result result) { final boolean wasTaskInvoked = mTaskInvoked.get(); if (!wasTaskInvoked) { postResult(result); } }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyygdg.html