本文会带领大家像看故事一样去理解AsyncTask的部分源码,首先我们来看一个AsyncTask的小程序
构造函数已经分析完了,现在该excute()了,进入execute()的源码(4)
最后总结一下onPreExecute()是在UI线程中执行的,doInBackground(Params... params)是在子线程中执行,该线程是在mFuture这个对象开辟的,它里面的run()调用mWorker的call()从而执行了postResult(doInBackground(Params...params)),publishProgress(Progress... values)因为要实时的获取进度所谓要在doInBackground中执行,从而也是在子线程中执行的。onProgressUpdate()和finish()是在通过sHandler来处理的而sHandler是属于UI线程中的,所以这两个方法都是在UI线程中进行
onPostExecute()是在finish()中调用的所以它也是在UI线程中执行!!!
public class MainActivity extends Activity {
private ProgressDialog dialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dialog = new ProgressDialog(this);
dialog.setMax(100);
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.setCancelable(false);
new MyAsyncTask().execute();
}
private class MyAsyncTask extends AsyncTask<Void, Integer, Void>{
@Override
protected Void doInBackground(Void... params) {
for (int i = 1; i <= 100; i++) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
publishProgress(i);
}
return null;
}
@Override
protected void onPreExecute() {
dialog.show();
super.onPreExecute();
}
@Override
protected void onProgressUpdate(Integer... values) {
dialog.setProgress(values[0]);
super.onProgressUpdate(values);
}
@Override
protected void onPostExecute(Void result) {
if(dialog!=null){
dialog.dismiss();
}
super.onPostExecute(result);
}
}
}
运行效果图如下:
现在我来一步一步按照执行的顺序来分析各部分源码
首先当然是new AsyncTask(),好我们去到构造方法里面看看
//*****(1)******AsyncTask.java
public AsyncTask() {
mWorker = new WorkerRunnable<Params, Result>() {//什么是WorkerRunnable看下面(2)
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) {//看到这里一定很好奇什么是FutureTask,往下看(3),这里分析完后那么已经把new MyAsyncTask()弄完了,现在该干嘛?当然是execute(),继续往下看
@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);
}
}
};
}
//******(2)*****AsyncTask.java
private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {
Params[] mParams;
}
知道什么是WorkerRunnable了吧,那好回到(1)继续
//*******(3)**********FutureTask.java
public FutureTask(Callable<V> callable) {//callable即我们的mWorker,后面的代码中还要用到mWorker,我们还要用它来调用call方法呢
if (callable == null)
throw new NullPointerException();
this.callable = callable;
this.state = NEW; // ensure visibility of callable
}
知道FutureTask是继承自Runnable的所以到此我们就开启了一个子线程
构造函数已经分析完了,现在该excute()了,进入execute()的源码(4)
//******(4)*******AsyncTask.java
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
return executeOnExecutor(sDefaultExecutor, params);//往下看这个方法(5)
}
//*******(5)************AsyncTask.java
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;//mStatus设置为Running
onPreExecute();//onPreExecute()就是在这执行的
mWorker.mParams = params;//还记得前面的mWorker吗?它里面就一个Params[] mParams
exec.execute(mFuture);//exec为sDefaultExecutor对象,什么是sDefaultExecutor我们往下看(6)
return this;
}
//********(6)************AsyncTask.java
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();//看这里,什么是r,就是我们的mFuture啊,不信你去(6)看看,好吧去看FutureTask的run()方法(7)
} finally {
scheduleNext();
}
}
});
if (mActive == null) {
scheduleNext();
}
}
protected synchronized void scheduleNext() {
if ((mActive = mTasks.poll()) != null) {
THREAD_POOL_EXECUTOR.execute(mActive);
}
}
}
//**********(7)**********FutureTask.java
//代码比较长是吧?别急我们只需要发来看关键部分即可
public void run() {
if (state != NEW ||
!UNSAFE.compareAndSwapObject(this, runnerOffset,
null, Thread.currentThread()))
return;
try {
Callable<V> c = callable;
//什么是callable还记得么?我们在前面讲了public FutureTask(Callable<V> callable){this.callable=callable}
//那不就是FutureTask构造方法的参数么—>mWorker,前面分析FutureTask的时候(1)我也提前讲过,不信自己去看
if (c != null && state == NEW) {
V result;
boolean ran;
try {
result = c.call();//mWorker.call()到最前面的看(1)
//postResult(doInBackground(mParams))主要看这个方法就可以了,而且参数使我们熟悉的doInBackground(mParams),往下看(8)
ran = true;
} catch (Throwable ex) {
result = null;
ran = false;
setException(ex);
}
if (ran)
set(result);
}
} finally {
// runner must be non-null until state is settled to
// prevent concurrent calls to run()
runner = null;
// state must be re-read after nulling runner to prevent
// leaked interrupts
int s = state;
if (s >= INTERRUPTING)
handlePossibleCancellationInterrupt(s);
}
}
//*********(8)***********AsyncTask.java
private Result postResult(Result result) {
@SuppressWarnings("unchecked")
Message message = sHandler.obtainMessage(MESSAGE_POST_RESULT,
new AsyncTaskResult<Result>(this, result));
message.sendToTarget();
return result;
}
对于上面的代码没有什么疑问吧?就是把message发送到sHandler去处理,那么下面看sHandler是个什么东西?他是InternalHandler的对象,看InternalHandle(9)
//********(9)*********AsyncTask.java
private static class InternalHandler extends Handler {
@SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
@Override
public void handleMessage(Message msg) {
AsyncTaskResult result = (AsyncTaskResult) msg.obj;
switch (msg.what) {
case MESSAGE_POST_RESULT://这个是有postResult发出来的,说明当postResult执行完之后这里就该执行啦
// There is only one result
result.mTask.finish(result.mData[0]);
//result是什么?AsyncTaskResult的对象,那么就来看看AsyncTaskResult是什么,往下看(10)
//OK知道AsyncTaskResult是什么了吧?mTask不就this么当前的AsyncTask对象啊,它调用finish方法。什么是finish()*****(11)
break;
case MESSAGE_POST_PROGRESS:
//这里啥时候回执行呢?别担心下面我来告诉你,看下面的publishProgress()******(12)
//Ok又回到这里了
result.mTask.onProgressUpdate(result.mData);//onProgressUpdate()这个也是我们熟悉的家伙吧。好啦到此为止我们就分析完啦
break;
}
}
}
/*******(10)**********AsyncTask.java
private static class AsyncTaskResult<Data> {
final AsyncTask mTask;
final Data[] mData;
AsyncTaskResult(AsyncTask task, Data... data) {
mTask = task;
mData = data;
}
}
知道AsyncTaskResult是什么了吧,那回到(9)继续看
//********(11)**********AsyncTask.java
private void finish(Result result) {
if (isCancelled()) {
onCancelled(result);
} else {
onPostExecute(result);//又看到我们熟悉的东西了吧
}
mStatus = Status.FINISHED;//这里mStatus的值变成了FINISHED,看完这里回到(9)
}
/*********(12)***********AsyncTask.java
protected final void publishProgress(Progress... values) {
if (!isCancelled()) {
sHandler.obtainMessage(MESSAGE_POST_PROGRESS,
new AsyncTaskResult<Progress>(this, values)).sendToTarget();
}
}
跟上面的postResult很像吧?虽然写法不一样都是发送信息给sHandler处理,这里的msg.what=MESSAGE_POST_PROGRESS,赶快去sHandler里面看看
最后总结一下onPreExecute()是在UI线程中执行的,doInBackground(Params... params)是在子线程中执行,该线程是在mFuture这个对象开辟的,它里面的run()调用mWorker的call()从而执行了postResult(doInBackground(Params...params)),publishProgress(Progress... values)因为要实时的获取进度所谓要在doInBackground中执行,从而也是在子线程中执行的。onProgressUpdate()和finish()是在通过sHandler来处理的而sHandler是属于UI线程中的,所以这两个方法都是在UI线程中进行
onPostExecute()是在finish()中调用的所以它也是在UI线程中执行!!!
好了分析完毕