0%

AsyncTask的解析

AsyncTask是android sdk封装的异步操作类。 隐藏了Thread、 Runnable以及其他对象, 方便开发者使用。

1. AsyncTask 的使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
		//第一个Integer是传递给AsyncTask的参数值的类型  
//第二个Integer是onProgressUpdate参数值的类型
//第三个Integer是doInBackground返回值的类型
AsyncTask<Integer, Integer, Integer> asyncTask = new AsyncTask<Integer, Integer, Integer>() {

@Override
protected Integer doInBackground(Integer... params) {
//这个方法是在子线程中执行
//这里获取传入的参数值
// params[0];//表示传入的第一个参数
// params[2];//表示传入的第二个参数
//进行耗时的操作
return null;//将值返回
}

@Override
protected void onPreExecute() {
//这个方法是在主线程中执行
//这个是在doInBackground执行之前会调用这个方法
super.onPreExecute();
}

@Override
protected void onPostExecute(Integer result) {
//这个方法是在主线程中执行
//这个是在doInBackground执行完成会调用这个方法
super.onPostExecute(result);
}

@Override
protected void onProgressUpdate(Integer... values) {
//这几个方法是不过主动调用的 需要自己在doInBackground调用publishProgress(Value), 然后就会执行这个方法, 从而更新界面。
super.onProgressUpdate(values);
}

@Override
protected void onCancelled(Integer result) {
//当在doInBackground异常终止会调用这个方法, 这个方法默认调用onCancelled()方法
super.onCancelled(result);
}

@Override
protected void onCancelled() {
super.onCancelled();
}



};
//开启任务的两种方式
//这个参数需要和上面的值类型对应.
// asyncTask.execute(这里是传递给AsyncTask的参数, 这里是可变长度参数);//开始执行任务, 使用默认的线程池
// asyncTask.executeOnExecutor(exec, params); //exec 是自定义的线程池
}
}

2. 任务执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
return executeOnExecutor(sDefaultExecutor, params);
}

public final AsyncTask<Params, Progress, Result> executeOnExecutor(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;
}

执行任务,如果不配置Executor将使用默认的线程池。

3. 注意的地方,默认线程池在执行任务的时候串行执行(当一个任务执行完成后才执行下一个任务)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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);
}
}

4 使用的是自定义runnable,为的是能够获取返回值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
mTaskInvoked.set(true);

Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
//noinspection unchecked
return postResult(doInBackground(mParams));
}
};

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 occured while executing doInBackground()",
e.getCause());
} catch (CancellationException e) {
postResultIfNotInvoked(null);
}
}
};

5 消息传递,最后执行完成还是通过Handler进行通信。

Handler源码解析

1
2
3
4
5
6
7
private Result postResult(Result result) {
@SuppressWarnings("unchecked")
Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
new AsyncTaskResult<Result>(this, result));
message.sendToTarget();
return result;
}