使用过AsyncTask的朋友,肯定都遇到过这样的情况,
AsyncTask 执行完(execute 调用完)一次之后,就不能用了,但是为什么不能用了?
其直接原因是这样 —— 状态机 校验 失败 。
状态机模式在复杂的、功能比较复杂的事务中,是非常常用的一种设计模式。
好了,我们来看看AsyncTask的实际代码情况
首先,状态机定义如下:
/**
* Indicates the current status of the task. Each status will be set only once
* during the lifetime of a task.
*/
public enum Status {
/**
* Indicates that the task has not been executed yet.
*/
PENDING,
/**
* Indicates that the task is running.
*/
RUNNING,
/**
* Indicates that {@link AsyncTask#onPostExecute} has finished.
*/
FINISHED,
}
我们来看看AysncTask中的是否存在Status 的使用,
一查代码,还真有,对应的属性名称为mStatus。
那么mStatus 在什么时候附的初始值?
找遍代码,只有一处,那就是对象初始化的时候
private volatile Status mStatus = Status.PENDING;
我们在来看一下execute方法,
在execute方法中,首先会触发下面的代码
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;
通过上面的代码,可以知道,在execute执行时,即调用过execute方法后,status 处于非PENDING,再次调用execute时,首先会进行状态校验,检验失败,直接抛出异常,停止执行了。
这就是AsyncTask只能使用一次的直接原因。