美文网首页
为什么AsyncTask一定要在主线程中创建?execute方法

为什么AsyncTask一定要在主线程中创建?execute方法

作者: simit | 来源:发表于2018-10-24 15:02 被阅读0次

    关于为什么AsyncTask一定要在主线程中创建?

    我们知道AsyncTask中UI的更新是通过InternalHandler实现的,这就说明InternalHandler必须是通过主线程的Loop来创建的。

    看源码

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

    InternalHandler的创建

    private static HandlergetMainHandler() {
    
    synchronized (AsyncTask.class) {
    
    if (sHandler ==null) {
    
    sHandler =new InternalHandler(Looper.getMainLooper());
    
            }
    
    return sHandler;
    
        }
    
    }
    

    在API26中,InternalHandler 是通过Looper.getMainLooper()创建的,所以AsyncTask不论是在子线程还是主线程中创建都无所谓。在Android开发艺术探索一书中之所以强调AsyncTask必须在主线程中创建是因为之前源码中InternalHandler的创建方式如下:

    private static final InternalHandler sHandler = new InternalHandler();
    

    是通过当前线程的Loop创建的,如果当前线程是子线程,那自然是行不通的。

    execute方法一定要在主线程中调用?

    execute的源码实现如下:
    
    @MainThread
    public final AsyncTaskexecute(Params... params) {
    
    return executeOnExecutor(sDefaultExecutor, params);
    
    }
    
    @MainThread
    
    public final AsyncTaskexecuteOnExecutor(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;
    
    }
    
    @MainThread
    
    protected void onPreExecute() {
    
    }
    

    通过源码可以看出,execute方法最先调用的是onPreExecute方法,而onPreExecute方法必须运行在主线程,如果一定要在子线程中调execute方法那就表示你不能在onPreExecute方法中做更新UI的操作,因为此时onPreExecute方法为子线程。onProgressUpdate, onPostExecute , onCancelled 方法仍然运行在主线程(通过InternalHandler回调到主线程)。

    相关文章

      网友评论

          本文标题:为什么AsyncTask一定要在主线程中创建?execute方法

          本文链接:https://www.haomeiwen.com/subject/xitxtqtx.html