AsyncTask作为android原生的处理异步任务的方案,问题很多,比如不允许多个任务同时运行,关于这一点,网上有很多说法,早期的说法是AsyncTask最初被引入的时候只支持一个任务同时运行,后期增加到了5个,我今天特意验证了一下看看:
private void start(View view){
for (int i = 0; i < 100; i++) {
new Task().execute();
}
}
class Task extends AsyncTask<Void,Void,Void>{
@Override
protected Void doInBackground(Void... voids) {
try {
int times = 100;
for (int i = 0; i < times; i++) {
System.out.println("thread"+Thread.currentThread()+i+"");
Thread.sleep(10);
}
} catch (Exception e) {
}
return null;
}
}
在for循环中开启了一百个异步任务,每个任务打印从0到99,每次打印sleep10毫秒,发现结果出乎意料:
03-29 16:36:09.323 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]0
03-29 16:36:09.334 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]1
03-29 16:36:09.344 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]2
03-29 16:36:09.354 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]3
03-29 16:36:09.365 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]4
03-29 16:36:09.375 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]5
03-29 16:36:09.385 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]6
03-29 16:36:09.396 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]7
03-29 16:36:09.406 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]8
03-29 16:36:09.416 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]9
03-29 16:36:09.426 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]10
03-29 16:36:09.437 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]11
03-29 16:36:09.447 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]12
03-29 16:36:09.457 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]13
03-29 16:36:09.468 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]14
03-29 16:36:09.478 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]15
03-29 16:36:09.488 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]16
03-29 16:36:09.499 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]17
03-29 16:36:09.509 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]18
03-29 16:36:09.520 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]19
03-29 16:36:09.531 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]20
03-29 16:36:09.541 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]21
03-29 16:36:09.552 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]22
03-29 16:36:09.562 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]23
03-29 16:36:09.573 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]24
03-29 16:36:09.583 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]25
03-29 16:36:09.594 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]26
03-29 16:36:09.606 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]27
03-29 16:36:09.617 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]28
03-29 16:36:09.627 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]29
03-29 16:36:09.638 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]30
03-29 16:36:09.649 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]31
03-29 16:36:09.659 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]32
03-29 16:36:09.670 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]33
03-29 16:36:09.681 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]34
03-29 16:36:09.692 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]35
03-29 16:36:09.703 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]36
03-29 16:36:09.713 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]37
03-29 16:36:09.724 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]38
03-29 16:36:09.734 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]39
03-29 16:36:09.745 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]40
03-29 16:36:09.755 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]41
03-29 16:36:09.766 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]42
03-29 16:36:09.776 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]43
03-29 16:36:09.787 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]44
03-29 16:36:09.797 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]45
03-29 16:36:09.808 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]46
03-29 16:36:09.818 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]47
03-29 16:36:09.828 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]48
03-29 16:36:09.839 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]49
03-29 16:36:09.849 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]50
03-29 16:36:09.860 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]51
03-29 16:36:09.870 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]52
03-29 16:36:09.880 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]53
03-29 16:36:09.891 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]54
03-29 16:36:09.902 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]55
03-29 16:36:09.913 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]56
03-29 16:36:09.923 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]57
03-29 16:36:09.934 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]58
03-29 16:36:09.944 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]59
03-29 16:36:09.955 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]60
03-29 16:36:09.965 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]61
03-29 16:36:09.976 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]62
03-29 16:36:09.986 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]63
03-29 16:36:09.997 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]64
03-29 16:36:10.007 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]65
03-29 16:36:10.018 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]66
03-29 16:36:10.028 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]67
03-29 16:36:10.038 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]68
03-29 16:36:10.049 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]69
03-29 16:36:10.059 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]70
03-29 16:36:10.070 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]71
03-29 16:36:10.080 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]72
03-29 16:36:10.091 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]73
03-29 16:36:10.101 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]74
03-29 16:36:10.112 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]75
03-29 16:36:10.122 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]76
03-29 16:36:10.133 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]77
03-29 16:36:10.143 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]78
03-29 16:36:10.153 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]79
03-29 16:36:10.164 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]80
03-29 16:36:10.174 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]81
03-29 16:36:10.184 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]82
03-29 16:36:10.195 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]83
03-29 16:36:10.206 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]84
03-29 16:36:10.216 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]85
03-29 16:36:10.227 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]86
03-29 16:36:10.237 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]87
03-29 16:36:10.248 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]88
03-29 16:36:10.258 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]89
03-29 16:36:10.269 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]90
03-29 16:36:10.279 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]91
03-29 16:36:10.290 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]92
03-29 16:36:10.301 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]93
03-29 16:36:10.311 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]94
03-29 16:36:10.322 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]95
03-29 16:36:10.332 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]96
03-29 16:36:10.343 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]97
03-29 16:36:10.353 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]98
03-29 16:36:10.364 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]99
03-29 16:36:10.375 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]0
03-29 16:36:10.386 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]1
03-29 16:36:10.396 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]2
03-29 16:36:10.407 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]3
03-29 16:36:10.417 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]4
03-29 16:36:10.428 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]5
03-29 16:36:10.438 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]6
03-29 16:36:10.448 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]7
03-29 16:36:10.459 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]8
03-29 16:36:10.469 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]9
03-29 16:36:10.480 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]10
03-29 16:36:10.491 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]11
03-29 16:36:10.502 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]12
03-29 16:36:10.512 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]13
03-29 16:36:10.523 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]14
03-29 16:36:10.534 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]15
03-29 16:36:10.544 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]16
03-29 16:36:10.555 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]17
03-29 16:36:10.565 10746-10813/com.example.rzm.appmarket I/System.out: threadThread[AsyncTask #4,5,main]18
......
在一个AsyncTask执行完成之前,另一个任务不会开始,也就是目前仍然,AsyncTask只能同时执行一个后台线程
接下来看源码
我们把AsyncTask的几个方法作为源码阅读的入口
execute 开始执行
cancel 取消执行
execute
//@MainThread 只能在主线程中开启
@MainThread
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
return executeOnExecutor(sDefaultExecutor, params);
}
我们知道,AsyncTask是通过线程池,Handler,Runnable集合来处理的,sDefaultExecutor继承自Executor,用来处理异步任务
public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
......
private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
......
private static class SerialExecutor implements Executor {
final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
Runnable mActive;
public synchronized void execute(final Runnable r) {
mTasks.offer(new Runnable() {
public void run() {
try {
r.run();
} finally {
scheduleNext();
}
}
});
if (mActive == null) {
scheduleNext();
}
}
protected synchronized void scheduleNext() {
if ((mActive = mTasks.poll()) != null) {
THREAD_POOL_EXECUTOR.execute(mActive);
}
}
}
executeOnExecutor
@MainThread
public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
Params... params) {
//判断当前任务的状态,如果不是未开始执行,而是正在执行或者已经执行
//完成就抛出异常,所以一个任务只能执行一次,这就是一个任务调用两次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;
//回调onPreExecute,重写此方法可进行一些初始化操作
onPreExecute();
//将参数存入worker的数组中
mWorker.mParams = params;
//这个exec就是刚刚传入的那个线程池类sDefaultExecutor,
//将mFuture传入,执行sDefaultExecutor的execute方法
exec.execute(mFuture);
return this;
}
这里看到了一个mFuture,这个mFuture是什么呢,它是在AsyncTask的构造方法中初始化的
public AsyncTask(@Nullable Looper callbackLooper) {
mHandler = callbackLooper == null || callbackLooper == Looper.getMainLooper()
? getMainHandler()
: new Handler(callbackLooper);
mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
mTaskInvoked.set(true);
Result result = null;
try {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
//noinspection unchecked
result = doInBackground(mParams);
Binder.flushPendingCommands();
} catch (Throwable tr) {
mCancelled.set(true);
throw tr;
} finally {
postResult(result);
}
return result;
}
};
mFuture = new FutureTask<Result>(mWorker) {
@Override
protected void 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);
}
}
};
}
构造方法中初始化了一个Handler,用于接收子线程的消息,mWorker和mFuture是结合在一起使用的,mWorker是一种继承自Callable实现的线程,这种线程不同于Runnable和Thread,第一,可以有返回值,第二,可以抛出异常信息
private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {
//之前传入的参数就是存在这里的
Params[] mParams;
}
FutureTask对Callable进行了一层包装,以保证这个线程可以被线程池执行,exec.execute(mFuture)线程池execute方法可以接受一个FutureTask对象
我们回到线程池Executor的execute方法中
private static class SerialExecutor implements Executor {
final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
Runnable mActive;
public synchronized void execute(final Runnable r) {
//execute方法执行,将这个Runnable任务加入mTasks
mTasks.offer(new Runnable() {
public void run() {
try {
r.run();
} finally {
scheduleNext();
}
}
});
if (mActive == null) {
scheduleNext();
}
}
protected synchronized void scheduleNext() {
if ((mActive = mTasks.poll()) != null) {
THREAD_POOL_EXECUTOR.execute(mActive);
}
}
}
我们可以看到ArrayDeque是一个集合
public class ArrayDeque<E> extends AbstractCollection<E>
mTasks.offer是将这个任务加入了集合的尾部,相当于一个任务队列,
public boolean offer(E e) {
return offerLast(e);
}
/**
* Inserts the specified element at the end of this deque.
*
* @param e the element to add
* @return {@code true} (as specified by {@link Deque#offerLast})
* @throws NullPointerException if the specified element is null
*/
public boolean offerLast(E e) {
addLast(e);
return true;
}
看到这里我们已经接近了为什么AsyncTask只能同时执行一个任务这个问题的答案了,看这里
public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
......
private static class SerialExecutor implements Executor {
final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
Runnable mActive;
public synchronized void execute(final Runnable r) {
//这里的操作只是将Runnable加入了mTasks
mTasks.offer(new Runnable() {
public void run() {
try {
r.run();
} finally {
scheduleNext();
}
}
});
//任务加入集合之后,执行这个方法,使用线程池
//来执行集合中的runnable任务,THREAD_POOL_EXECUTOR.execute(mActive);
if (mActive == null) {
scheduleNext();
}
}
protected synchronized void scheduleNext() {
if ((mActive = mTasks.poll()) != null) {
THREAD_POOL_EXECUTOR.execute(mActive);
}
}
}
SerialExecutor是一个静态类,那么一旦初始化之后就会一直存在了,所有的AysyncTask共享这一个Executor,在第一个任务加入线程队列之后,取出第一个task开始执行第一个任务,并且给mActive附了值,此时mActive已经不再满足mActive==null的判断条件,也就是,在这个任务执行完成之前,如果有新的任务过来被加入任务队列,那么由于mActive==null的条件不成立,scheduleNext方法没法执行,这个任务就不会马上被执行,而是等待上一个任务完成之后再次调用scheduleNext开启下一个任务
当第一个Runnable中的异步任务执行完成的时候,会再执行scheduleNext()方法,从线程队列中取出下一个任务开始执行,所以说AsyncTask的任务执行顺序就是加入线程队列的前后顺序,到这里,最初的问题解决了,AsyncTask的确是一次只能同时执行一个任务
大概有人看到这里会觉得疑惑,对于这句话”当第一个Runnable中的异步任务执行完成的时候,会再执行scheduleNext()方法“中的Runnable中的异步任务指的是什么觉得不解,如果刚才的流程还记得的话,你会知道这个Runnable中的异步任务其实就是exec.execute(mFuture)传过来的FutureTask中包装的Callable,FutureTask也是最终实现了Runnable接口,所以r.run()中的r就是这个FutureTask。那么既然是异步任务,为什么要说当他执行完成的时候才会执行scheduleNext方法呢,按常理讲,应该是同时进行的,这里就涉及到了Callable线程的一种特性
Callable线程运行过程中,会阻塞当前线程,直到执行完成获得执行结果
这也是为什么将Runnable往线程队列中加的时候,要在这个Callable线程的外边再加一个Runnable,为什么不直接把这个Callable加入队列中,因为Callable有这个特性,导致他执行的时候会阻塞当前线程,那么如果直接加入集合,执行的时候直接执行这个Callable,那么就会导致主线程被阻塞,因为当前还是主线程,所以必须在Runnable中执行这个Callable
所以当他运行的时候,当前线程被阻塞,那么
finally {
scheduleNext();
}
不会被立即执行,而是等待他执行完成,一个任务执行完成之后,调用scheduleNext执行下一个任务
这时候我们再回到WorkerRunnable中,这里就是每一个任务执行的地方
mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
mTaskInvoked.set(true);
Result result = null;
try {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
//noinspection unchecked
//回调doInBackground方法,执行我们的异步任务
result = doInBackground(mParams);
Binder.flushPendingCommands();
} catch (Throwable tr) {
mCancelled.set(true);
throw tr;
} finally {
postResult(result);
}
return result;
}
};
当任务执行完成后,执行finally中的postResult方法,发送消息到Handler主线程
private Result postResult(Result result) {
@SuppressWarnings("unchecked")
Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
new AsyncTaskResult<Result>(this, result));
message.sendToTarget();
return result;
}
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;
}
}
}
调用AsyncTask的finish方法,并传递任务执行结果
private void finish(Result result) {
if (isCancelled()) {
onCancelled(result);
} else {
//回调onPostExecute,一个任务完成
onPostExecute(result);
}
mStatus = Status.FINISHED;
}
下面我们再从cancel方法这个切入点去看源码
public final boolean cancel(boolean mayInterruptIfRunning) {
mCancelled.set(true);
return mFuture.cancel(mayInterruptIfRunning);
}
调用的是FutureTask的cancel方法
public boolean cancel(boolean mayInterruptIfRunning) {
if (!(state == NEW &&
U.compareAndSwapInt(this, STATE, NEW,
mayInterruptIfRunning ? INTERRUPTING : CANCELLED)))
return false;
try { // in case call to interrupt throws exception
if (mayInterruptIfRunning) {
try {
Thread t = runner;
if (t != null)
t.interrupt();
} finally { // final state
U.putOrderedInt(this, STATE, INTERRUPTED);
}
}
} finally {
finishCompletion();
}
return true;
}
finishCompletion
private void finishCompletion() {
// assert state > COMPLETING;
for (WaitNode q; (q = waiters) != null;) {
if (U.compareAndSwapObject(this, WAITERS, q, null)) {
for (;;) {
Thread t = q.thread;
if (t != null) {
q.thread = null;
LockSupport.unpark(t);
}
WaitNode next = q.next;
if (next == null)
break;
q.next = null; // unlink to help gc
q = next;
}
break;
}
}
done();
callable = null; // to reduce footprint
}
最终还是走到done方法中
网友评论