Android开发:AsyncTask源码解析(2)

先设置线程级别为THREAD_PRIORITY_BACKGROUND(10),Linux线程级别从-20(最高)~19(最低),普通级别值为0,因而THREAD_PRIORITY_BACKGROUND级别比普通级别低
然后执行AsyncTask的doInBackground方法,并返回结果。所以当我们把耗时的工作量放在doInBackground方法里执行时,实际上是把大工作量放到了一个低级别的线程中去执行。

FutureTask中的run方法调用完callable.call()并获得结果之后就会调用set(result)方法,我们来看看set方法

protected void set(V v) {       sync.innerSet(v);   }  

调用sync的innerSet方法:

void innerSet(V v) {           for (;;) {               ...               if (compareAndSetState(s, RAN)) {                   result = v;                   releaseShared(0);                   done();//调用了FutureTask的done();方法                    return;               }           }       }  

innerSet中又调用了mFuture的done方法,我们来看看done方法

mFuture = new FutureTask<Result>(mWorker) {               @Override               protected void done() {                   Message message;                   Result result = null;                      try {                       result = get();//调用FutureTask的get方法,该方法 如有必要,等待计算完成,然后获取其结果。                    } catch (InterruptedException e) {                       Android.util.Log.w(LOG_TAG, e);                   } catch (ExecutionException e) {                       throw new RuntimeException("An error occured while executing doInBackground()",                               e.getCause());                   } catch (CancellationException e) {                       message = sHandler.obtainMessage(MESSAGE_POST_CANCEL,                               new AsyncTaskResult<Result>(AsyncTask.this, (Result[]) null));//取消任务,由sHandler去处理                        message.sendToTarget();                       return;                   } catch (Throwable t) {                       throw new RuntimeException("An error occured while executing "                               + "doInBackground()", t);                   }                      message = sHandler.obtainMessage(MESSAGE_POST_RESULT,                           new AsyncTaskResult<Result>(AsyncTask.this, result));                   message.sendToTarget();               }           };  

FutureTask的get()方法会等待线程的执行结果,在等待的过程中用户可能会执行mFuture的cancel方法来取消任务

 public final boolean cancel(boolean mayInterruptIfRunning) {       return mFuture.cancel(mayInterruptIfRunning);   }  

此时done()中get()会抛出CancellationException异常,捕获取消任务异常,转由sHandler去处理异常,

...   catch (CancellationException e) {                       message = sHandler.obtainMessage(MESSAGE_POST_CANCEL,                               new AsyncTaskResult<Result>(AsyncTask.this, (Result[]) null));//取消任务,由sHandler去处理                        message.sendToTarget();                       return;                   }                    ...  

而get()顺利获取到结果时也转由sHandler来处理

...   message = sHandler.obtainMessage(MESSAGE_POST_RESULT,           new AsyncTaskResult<Result>(AsyncTask.this, result));   message.sendToTarget();   ...  

我们来看看sHandler,sHandler为InternalHandler,该类是AsyncTask的内部类

 

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;               }           }       }  

    该handler的handleMessage集中来处理任务执行的完成情况
    1、MESSAGE_POST_RESULT,成功执行完任务时,调用AsyncTask的finish(result)方法,参数为返回的结果

AsyncTask的finish(result)方法:       private void finish(Result result) {          if (isCancelled()) result = null;          onPostExecute(result);          mStatus = Status.FINISHED;      }  

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

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