最开始的异步,应该是使用AsyncTask处理的比较多,都知道AsyncTask常用的三个方法:onPreExecute onPostExecute doInBackground
前两个是在UI线程,最后一个doInBackground
是在子线程,可以处理一些耗时操作。简单分析一下这三个方法:
1,最常见使用方式如下:
AsyncTask mAsyncTask = new AsyncTask<Void, Void, Void>() {
@Override
protected void onPreExecute() {
super.onPreExecute();
//ui线程
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
//UI线程
}
@Override
protected Void doInBackground(Void... voids) {
//子线程,处理耗时操作
return null;
}
};
mAsyncTask.execute();//开始执行,就从这个方法入手
2,跟到mAsyncTask.execute();
中可以看到:
@MainThread
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
//调用了下面的方法
return executeOnExecutor(sDefaultExecutor, params);
}
接着(下面这段代码,也说明了为什么AsyncTask只能执行一次,具体看注释):
@MainThread
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(); //在这里,就调用了,文章最开始说的方法,同时也是在UI线程运行
mWorker.mParams = params;
exec.execute(mFuture); //紧接着调用该方法,跟到 mFuture
return this;
}
3,接着分析:exec.execute(mFuture);
:
- 首先看看
mFuture
是个什么东西:
private final FutureTask<Result> mFuture;//声明
....//省略好多代码
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);
}
}
};
- FutureTask 其实是实现了Runnable 接口,相当于一个线程(所以必定有run方法)
public class FutureTask<V> implements RunnableFuture<V>{
....
public FutureTask(Callable<V> callable) {
if (callable == null)
throw new NullPointerException();
this.callable = callable;
this.state = NEW; // ensure visibility of callable
}
...
}
- FutureTask 的run方法,这里注意
callable
其实就是AsyncTask
中的mWorker
.....
public void run() {
if (state != NEW ||
!U.compareAndSwapObject(this, RUNNER, null, Thread.currentThread()))
return;
try {
Callable<V> c = callable; //注意这里,其实就是上面构造器传入的 mWorker
if (c != null && state == NEW) {
V result;
boolean ran;
try {
result = c.call(); //在这里,调用了 mWorker 的call方法
ran = true;
} catch (Throwable ex) {
result = null;
ran = false;
setException(ex);
}
if (ran)
set(result);
}
} finally {
runner = null;
int s = state;
if (s >= INTERRUPTING)
handlePossibleCancellationInterrupt(s);
}
}
.....
4,回到AsyncTask 的mWorker
,也就是在这里调用了doInBackground
方法,执行完毕后,调用postResult(result);
方法:
mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
mTaskInvoked.set(true);
Result result = null;
try {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
//在这里调用了该方法,并且他是Runnable,也就是子线程
result = doInBackground(mParams);
Binder.flushPendingCommands();
} catch (Throwable tr) {
mCancelled.set(true);
throw tr;
} finally {
//最后调用 该方法
postResult(result);
}
return result;
}
};
5,postResult
方法(其实就是一个handler,发送 MESSAGE_POST_RESULT 切换到了UI线程):
private Result postResult(Result result) {
@SuppressWarnings("unchecked")
Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
new AsyncTaskResult<Result>(this, result));
message.sendToTarget();
return result;
}
可以搜索到,MESSAGE_POST_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:
// 注意这里
result.mTask.finish(result.mData[0]);
break;
case MESSAGE_POST_PROGRESS:
result.mTask.onProgressUpdate(result.mData);
break;
}
}
}
此时,只需要看看 result.mTask.finish(result.mData[0]);
这里做了哪些操作就可以。
private void finish(Result result) {
if (isCancelled()) {
//如果cancel 就执行该方法
onCancelled(result);
} else {
onPostExecute(result);//执行了该方法
}
//状态置为:finish
mStatus = Status.FINISHED;
}
@SuppressWarnings({"RawUseOfParameterizedType"})
private static class AsyncTaskResult<Data> {
final AsyncTask mTask;
final Data[] mData;
AsyncTaskResult(AsyncTask task, Data... data) {
mTask = task;//这里的task也就是AsyncTask,调用了上面的finish方法
mData = data;
}
}
over...
上面简单分析了一下AsyncTask,其实分析下来也就是这几个类:AsyncTask
,FutureTask
相互传参调用,还有如果是UI和子线程通讯,一定会使用到handler,这样分析也就稍微简单了一点!
网友评论