美文网首页
为什么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