目录
AsyncTask源码分析,当前使用的Android 6.0的代码,AsyncTask源码目录在如下:
base\core\java\android\os\AsyncTask.java
在分析源码之前,我们看看我们在项目中是如何使用AsyncTask的。
下面是个简单的demo,只是写了AsyncTask使用的大致步骤。(AsyncTask是个抽象类,因此需要我们继承并实现其抽象方法doInBackground())
/**
* 实现AsyncTask
*
* @author
*
*/
private class MyAsyncTask extends AsyncTask<String, Void, Void> { //这里只是参数,不返回结果,所以后面的参数设置为Void
@Override
protected Void doInBackground(String... params) {
// TODO Auto-generated method stub
// 后台运行线程
publishProgress(); //5.更新进度值.调用此句后才会执行onProgressUpdate()
return null;
}
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
// 主线程,源码中特意注明
super.onPreExecute();
}
@Override
protected void onProgressUpdate(Void... values) {
// TODO Auto-generated method stub
// 主线程,更新进度
super.onProgressUpdate(values);
}
@Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
// 主线程,返回结果
super.onPostExecute(result);
}
}
//仅仅简单测试,如果要访问网络,需要配置网络权限
String url = "http://www.biumall.com/index.html";
MyAsyncTask myAsyncTask = new MyAsyncTask(); //[1.AsyncTask构造函数初始化]
myAsyncTask.execute(url);[2.execute()运行]
1. AsyncTask构造函数初始化
MyAsyncTask myAsyncTask = new MyAsyncTask();
MyAsyncTask的初始化直接调用了父类的AsyncTask的默认构造函数
/**
* Creates a new asynchronous task. This constructor must be invoked on the UI thread.
*/
public AsyncTask() {
//[1.1 WorkerRunnable实现了Callable接口]
mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
mTaskInvoked.set(true);
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
//noinspection unchecked
Result result = doInBackground(mParams); //[1.2 doInBackground()方法在这里调用]
Binder.flushPendingCommands();
return postResult(result); //[1.3 psotResult() ]
}
};
//[1.4 FutureTask ]
mFuture = new FutureTask<Result>(mWorker) {
@Override
protected void done() { //Callable在call()方法中返回的结果在这里通过get()方法获取,然后postResultIfNotInvoked()范湖结果
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);
}
}
};
}
1.1 WorkerRunnable实现了Callable接口
private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {
Params[] mParams;
}
Callable也是类似也Runnable,call()运行在子线程中
具体了解Callable的使用,请访问《Callable的简单使用》
1.2 doInBackground()的调用
doInBackground()计算是运行在WorkerRunnable中的call()中的,但此DoInBackground()方法是个抽象的,所以子类必须实现
/**
* Override this method to perform a computation on a background thread. The
* specified parameters are the parameters passed to {@link #execute}
* by the caller of this task.
*
* This method can call {@link #publishProgress} to publish updates
* on the UI thread.
*
*/
@WorkerThread
protected abstract Result doInBackground(Params... params);
doInBackground()运行在工作线程(子线程)中的,抽象方法,我们会在实现类(demo中的MyAsyncTask类中)中进行复杂耗时计算。
在这个方法中我们可以调用publishProgress调用这个方法把工作线程的计算进度发送到主线程中更新UI,并回调onProgressUpdate()这个方法
/**
* Runs on the UI thread after {@link #publishProgress} is invoked.
* The specified values are the values passed to {@link #publishProgress}.
*
* @param values The values indicating progress.
*
* @see #publishProgress
* @see #doInBackground
*/
@SuppressWarnings({"UnusedDeclaration"})
@MainThread
protected void onProgressUpdate(Progress... values) {
}
在onProgressUpdate()方法中我们可以更新UI界面和提示计算进度(友好提示)
在工作线程中计算后,需要把结果传给主线程,我们继续
1.3 postResult()
private Result postResult(Result result) {
@SuppressWarnings("unchecked")
//handler消息机制
Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT, //[1.5 Handler消息机制返回计算结果]
new AsyncTaskResult<Result>(this, result));
message.sendToTarget();
return result;
}
在postResult()中,我们看到了Handler机制,,,也就是说,工作线程和子线程通信还是通过Handler机制来的。
在WorkRunnable中的call()方法是会返回Result的,这个值可以通过FutureTask的get()方法获取的。
1.4 FutureTask
在FutureTask中,等到WorkRunnable计算完后,会调用postResultIfNotInvoked(),直接进入源码
public final Result get() throws InterruptedException, ExecutionException {
return mFuture.get();
}
get()方法里运行的就是Future.get()方法。这里会等到WorkRunnable计算结果,一直阻塞。
private void postResultIfNotInvoked(Result result) {
final boolean wasTaskInvoked = mTaskInvoked.get();
if (!wasTaskInvoked) {
postResult(result);
}
}
private Result postResult(Result result) {
@SuppressWarnings("unchecked")
Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT, //[1.5 Handler消息机制返回计算结果]
new AsyncTaskResult<Result>(this, result));
message.sendToTarget();
return result;
}
最后还是走到postResult()中,,,又跟Handler消息机制挂上钩了。
1.5 Handler消息机制返回计算结果
private void finish(Result result) {
if (isCancelled()) {//如果取消了,就不返回结果;反之把结果返回到onPostExecute()这个方法我们在实现AsyncTask中时重写
onCancelled(result);
} else {
onPostExecute(result); //返回到主线程了
}
mStatus = Status.FINISHED;
}
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]); //[看finish()方法中的定义]
break;
case MESSAGE_POST_PROGRESS:
result.mTask.onProgressUpdate(result.mData); //[这个是更新进度状态,在doInBackground()中调用publishProgress()]
break;
}
}
}
上面只是根据代码分析,并没有根据实际运行流程走。通过上面我们知道AsyncTask中工作线程和主线程交互依旧使用Handler消息机制的。
2. execute()方法执行
AsyncTask构造函数初始化后,我们调用execute()方法运行程序的。
myAsyncTask.execute(url);[2.execute()运行]
我们进入execute()方法
/**
* Executes the task with the specified parameters. The task returns
* itself (this) so that the caller can keep a reference to it.
*/
@MainThread
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
return executeOnExecutor(sDefaultExecutor, params);
}
execute()方法中并没有做任何处理,而是直接调用了executeOnExecutor()方法
/**
* Executes the task with the specified parameters. The task returns
* itself (this) so that the caller can keep a reference to it.
*/
@MainThread
public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
Params... params) {
//判断当前AsyncTask的状态,有三种状态
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(); //执行onPreExecute()代码,这个是运行我们重写的onPreExecute()方法
mWorker.mParams = params; //设置传入的参数
exec.execute(mFuture); //[2.1 开启工作线程]
return this;
}
在executeOnExecutor()方法中,就行了当前AsyncTask的状态判断。
AsyncTask中有三种状态
/**
* Indicates the current status of the task. Each status will be set only once
* during the lifetime of a task.
*/
public enum Status {
/**
* Indicates that the task has not been executed yet.
*/
PENDING,
/**
* Indicates that the task is running.
*/
RUNNING,
/**
* Indicates that {@link AsyncTask#onPostExecute} has finished.
*/
FINISHED,
}
如果此时是RUNNING或者FINISHED,再次运行AsyncTask时就会抛出异常。
2.1 开启工作线程
exec.execute(mFuture);中的exec就是SerialExecutor 的对象,而SerialExecutor 继承于Executor 。
直接看代码
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);
}
}
}
在run()方法中就运行了mFuture.run(),最后一定会执行scheduleNext(),不过最终调用的都是线程池
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
private static final int CORE_POOL_SIZE = CPU_COUNT + 1;
private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
private static final int KEEP_ALIVE = 1;
private static final ThreadFactory sThreadFactory = new ThreadFactory() {
private final AtomicInteger mCount = new AtomicInteger(1);
public Thread newThread(Runnable r) {
return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());
}
};
private static final BlockingQueue<Runnable> sPoolWorkQueue =
new LinkedBlockingQueue<Runnable>(128);
/**
* An {@link Executor} that can be used to execute tasks in parallel.
*/
public static final Executor THREAD_POOL_EXECUTOR
= new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,
TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);
到这里就运行工作线程了,然后通过FutureTask.get()获取计算结果,再返回结果,AsyncTask就基本分析结束了。