这里直接拿以前写过的一个小Demo,根据这个Demo来分析源码。
public class MainActivity extends ActionBarActivity {
...
Private MyAsyncTask asyncTask;
protected void onCreate(Bundle savedInstanceState) {
...
asyncTask = new MyAsyncTask();
// 点击button进行异步任务
button.setOnClickListener(new OnClickListener() {
...
asyncTask.execute("Leelit"); // 这个参数就是传入参数,常用于URL网络下载,可以为空。
}
});
}
/* 泛型类AsyncTask有三个参数:Params,传入参数;Progress,进度;Result,返回结果。也可以使用Void表示该参数为空。*/
private class MyAsyncTask extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... string) {
// TODO Auto-generated method stub
String conutString = string[0]; // 字符串可变参数
int z = 0;
// 进行5亿次计算,模拟一个耗时任务
for (int i = 0; i < 1000000; i++) {
for (int j = 0; j < 500; j++) {
z++;
}
}
conutString += " has executed ++ computation for " + z + " times";
Log.e("ProcessInfo", "the task is done");
return conutString; // 将计算结果返回,传给onPostExecute()
}
@Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
textView.setText(result); // 刷新UI
}
}
}
public AsyncTask() {
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);
}
}
};
}
可以看到,AsyncTask的构造函数主要是实例化了mWorker
和mFuture
两个对象,看下这两个对象所属类。
private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {
Params[] mParams;
}
WorkerRunnable是个抽象类,实现了Callable接口,需要在子类里面重写call方法,并且里面有参数字段。而这个抽象方法返回postResult(doInBackground(mParams))
,postResult方法返回一个result,并且内部通过Handler将结果发送给主线程。而mFuture这个对象可以看作是对mWorker对象的包装。
private Result postResult(Result result) {
@SuppressWarnings("unchecked")
Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
new AsyncTaskResult<Result>(this, result));
message.sendToTarget();
return result;
}
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
return executeOnExecutor(sDefaultExecutor, params);
}
这个方法又继续调用了executeOnExecutor方法
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;
}
传入的参数分别为sDefaultExecutor
和params
,由此方法可知,任务是只会被执行一次的,否则抛出异常。
executeOnExecutor
方法进行:
mStatus = Status.RUNNING
,设置任务的状态onPreExecute()
,调用这个可能重写的方法,这也是用户感知的第一步mWorker.mParams = params
,设置任务的参数exec.execute(mFuture)
,执行这个任务,上面也说了可以把mFuture当成是mWorker的封装。接下来看下最后的exec.execute(mFuture)
方法,注意这个execute
是指sDefaultExecutor
的execute
方法了,这里易与AsyncTask的execute方法混淆。
public static void execute(Runnable runnable) {
sDefaultExecutor.execute(runnable);
}
重点看下sDefaultExecutor这个类
private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
sDefaultExecutor是一个SerialExecutor对象,接着看SerialExecutor类。
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);
}
}
}
一步一步走下来,最后的execute方法就是通过一个任务队列和一个线程池来执行任务,这个线程池在不同版本参数也所有不同。
public static final Executor THREAD_POOL_EXECUTOR
= new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,
TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);
最后我们来看下Handler是怎样处理message的
private static class InternalHandler extends Handler {
public InternalHandler() {
super(Looper.getMainLooper());
}
@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;
}
}
}
可以看到有两个状态,MESSAGE_POST_RESULT
代表任务完成,此时调用finish
方法,这个方法内部的主要逻辑就是调用onPostExecute()方法,而MESSAGE_POST_RESULT
就代表进度,此时调用的则是onProgressUpdate
方法。
很明显,当我们在重写的doInBackground方法调用publishProgress时,handler就会发送包含MESSAGE_POST_PROGRESS
状态的message。
protected final void publishProgress(Progress... values) {
if (!isCancelled()) {
getHandler().obtainMessage(MESSAGE_POST_PROGRESS,
new AsyncTaskResult<Progress>(this, values)).sendToTarget();
}
}
postResult(doInBackground(mParams)
,postResult方法则是通过handler发送消息给主线程,最后再用一个mFuture对象封装mWorker对象。onPreExecute
方法,设置mWorker参数,调用sDefaultExecutor.execute(mFuture);THREAD_POOL_EXECUTOR.execute(mActive)
,用一个线程池,串行
执行任务。执行流程:
在3.0版本之前任务是可以并发执行的,3.0后就串行了,如果我们需要在3.0版本之后并发执行任务,则可以调用executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,params),而不用内部维护一个串行任务队列的sDefaultExecutor。
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/leelit/article/details/46821437