5,线程切换和管理
5.1,线程切换
AsyncTask中4个方法执行所在的线程如下,是如何切换的呢?
onPreExecute //主线程,执行任务之前的一些UI操作
doInBackground //子线程,执行任务
onProgressUpdate // 任务执行时更新进度信息
onPostExecute // 主线程,任务完成时更新UI
利用内部类InternalHandler,定义如下, InternalHandler代表主线程
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;
}
}
}
并且通过getHandler方法可以获取该handler
private static Handler getHandler() {
synchronized (AsyncTask.class) {
if (sHandler == null) {
sHandler = new InternalHandler();
}
return sHandler;
}
}
1, onPreExecute
@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;
}
刚开始还没有利用线程池,所以自然在主线程中。
2, doInBackground
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);
Binder.flushPendingCommands();
return postResult(result);
}
};
是线程池中的线程回调,所以doInBackground运行于子线程中。
3, onProgressUpdate/ onPostExecute
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;
}
}
}
InternalHandler定义如下,可以看到,最后通过handler发送消息的方法切换到主线程中执行finish/ onProgressUpdate,并且finish方法中会调用onPostExecute方法,所以onProgressUpdate/ onPostExecute 在主线程中执行。
5.2,线程管理
AsyncTask主要有二个部分:一个是与主线各的交互,另一个就是线程的管理调度。
虽然可能多个AsyncTask的子类的实例,但是AsyncTask的内部Handler和ThreadPoolExecutor都是进程范围内共享的,
其都是static的,也即属于类的,类的属性的作用范围是CLASSPATH,因为一个进程一个VM,所以是AsyncTask控制着进程范围内所有的子类实例。
内部会创建一个进程作用域的线程池来管理要运行的任务,也就就是说当调用了AsyncTask#execute()后,
AsyncTask会把任务交给线程池,由线程池来管理创建Thread和运行Therad。