AsyncTask使用方法
AsyncTask是抽象类,所以使用的时候需要创建一个继承AsyncTask的子类。
private class MyAsyncTask extends AsyncTask<Void,Integer,String>{
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected String doInBackground(Void... voids) {
int progress =0;
publishProgress(progress);
return null;
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
}
}
三个泛型参数的含义:
-
Params :在执行AsyncTask时需要传入的参数,可用于在后台任务中使用。
-
Progress : 后台任务执行时,如果需要在界面上显示当前的进度,则使用这里指定的泛型作为进度单位。
-
Result :当任务执行完毕后,如果需要对结果进行返回,则使用这里指定的泛型作为返回值类型。
四个重写方法的含义:
-
onPreExecute():在执行后台操作之前调用,运行在主线程中;
-
doInBackground(Void… voids):核心方法,执行后台耗时操作的方法,必须实现的一个方法,运行在子线程中。如果需要更新进度可以调用publishProgress(Progress…)方法。
-
onProgressUpdate(Integer… values):当在后台任务中调用了publishProgress(Progress…)方法后,这个方法就很快会被调用,用于更新进度,运行在主线程中;
-
onPostExecute(Result):后台耗时操作完成后调用,运行在主线程中;
执行AsyncTask:
new MyAsyncTask().execute();
以上则是AsyncTask的一些简单使用方法,而想要知道知道AsyncTask的各个方法间的联系,就需要了解一下AsyncTask的源码了。
这里从new MyAsyncTask().execute();
执行方法开始研究AsyncTask的工作原理。
首先看下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);
}
}
};
}
AsyncTask的构造方法中初始化了三个对象,mHandler,mWorker ,mFuture 。
mWorker是一个实现了Callable的Callable对象。
private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {
Params[] mParams;
}
mFuture 是一个FutureTask对象,并且在初始化mFuture的时候将mWorker当参数传入FutureTask中。
好了,回到new MyAsyncTask().execute();
查看execute()
方法源码:
@MainThread
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
return executeOnExecutor(sDefaultExecutor, params);
}
就一行代码,会执行executeOnExecutor(sDefaultExecutor, params)
方法。该方法有两个参数,一个是静态的 Executor 对象,令一个是执行时的可选参数。再来executeOnExecutor()
方法的源码:
@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();
mWorker.mParams = params;
exec.execute(mFuture);
return this;
}
可以看到,这个时候AsyncTack已经执行到onPreExecute();
方法了。
而AsyncTask在构造方法中已经初始化了mWorker,mFuture。
exec.execute(mFuture);
执行FutureTask任务,mWorker中的方法得到执行。
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;
}
};
此时doInBackground()方法得到执行并且得到doInBackground中返回的result,再来看一定会执行的finally{}中的 postResult(result)方法:
private Result postResult(Result result) {
@SuppressWarnings("unchecked")
Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
new AsyncTaskResult<Result>(this, result));
message.sendToTarget();
return result;
}
这里面就是一个handler发送消息的一个机制,在InternalHandler中接收消息。
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;
}
}
}
InternalHandler中收到消息,执行result.mTask.finish(result.mData[0]);
方法。
查看finish()方法:
private void finish(Result result) {
if (isCancelled()) {
onCancelled(result);
} else {
onPostExecute(result);
}
mStatus = Status.FINISHED;
}
这里有个判断,如果AsyncTask没有取消就执行onPostExecute(result);
从new MyAsyncTask().execute();
执行,到现在我们已经经历了
onPreExecute();
→doInBackground(mParams)
→onPostExecute(result);
方法了。
我们知道当我们在doInBackground(),方法中调用publishProgress(progress);
方法的时候,onProgressUpdate(Integer... values)
方法才会被调用,那就看一下publishProgress()方法到底干了啥:
@WorkerThread
protected final void publishProgress(Progress... values) {
if (!isCancelled()) {
getHandler().obtainMessage(MESSAGE_POST_PROGRESS,
new AsyncTaskResult<Progress>(this, values)).sendToTarget();
}
}
和刚刚发送doInBackground()方法中返回的result一样的,这里也是一个handler消息机制发送消息,并且在InternalHandler中接收
case MESSAGE_POST_PROGRESS:
result.mTask.onProgressUpdate(result.mData);
break;
此时,AsyncTask中所有的方法也都得到执行了。以各个方法的执行流程来解析理解AsyncTask的原理是不是更加容易点呢,我是这样来理解的。