Android|Android AsyncTask源码阅读
AsyncTask 封装了新建后台工作线程再用Handler更新UI的过程。在官方文档也说明这个类最好用于时间短的操作,如果要保持线程长连接,还是推荐使用Executor、ThreadPoolExecutor等APIs.
AsynTask有三个范型参数(Params, Progress ,Result)和四个顺序调用的方法。
- onPreExecute
- doInBackground 此方法是虚方法,必须实现的。
- onProgressUpdate
- onPostExecute
AsyncTask execute = new AsyncTask() {
@Override
protected String doInBackground(String... strings) {
Log.e(TAG, "doInBackground");
return "" + strings;
}}.execute("leavesC");
AsyncTask构造方法 【Android|Android AsyncTask源码阅读】AsyncTask有三个构造方法:
public AsyncTask()
public AsyncTask(Handler)
public AsyncTask(Looper)
最后都会调用下面这个构造方法,核心代码重要思路都在这个方法里面
public AsyncTask(@Nullable Looper callbackLooper) {
//初始化mHandler
mHandler = callbackLooper == null || callbackLooper == Looper.getMainLooper()
? getMainHandler()
: new Handler(callbackLooper);
//WokerRunable 是抽象类,实现Callable接口。源码如下文
mWorker = new WorkerRunnable() {
public Result call() throws Exception {
//AtomicBoolean 实例 mTaskInvoked
mTaskInvoked.set(true);
Result result = null;
try {
//设置线程优先线
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
//noinspection unchecked
//调用doInBackground并且获得返回
result = doInBackground(mParams);
//刷新Pending命名
Binder.flushPendingCommands();
} catch (Throwable tr) {
//异常处理
//AtomicBoolean mCancelled = new AtomicBoolean();
mCancelled.set(true);
//抛出异常
throw tr;
} finally {
postResult(result);
}
return result;
}
};
//java的FutureTask 实例化
mFuture = new FutureTask(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);
}
}
};
}
postResultIfNotInvoked() 方法
private void postResultIfNotInvoked(Result result) {
// private final AtomicBoolean mTaskInvoked = new AtomicBoolean();
//原子类AtomicBoolean 实例mTaskInvoked
final boolean wasTaskInvoked = mTaskInvoked.get();
if (!wasTaskInvoked) {
//发送结果
postResult(result);
}
}
//我们熟悉的handler发送消息
private Result postResult(Result result) {
@SuppressWarnings("unchecked")
Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
new AsyncTaskResult(this, result));
message.sendToTarget();
return result;
}
AsyncTaskResult 异步结果包装类 使用了范型
private static class AsyncTaskResult {
final AsyncTask mTask;
final Data[] mData;
AsyncTaskResult(AsyncTask task, Data... data) {
mTask = task;
mData = https://www.it610.com/article/data;
}
}
WokerRunable 类 实现Callable接口至于Callable的作用笔者前面的文章有仔细说明。请自行查阅。
private static abstract class WorkerRunnable implements Callable {
Params[] mParams;
}
execute()方法
public final AsyncTask execute(Params... params) {
return executeOnExecutor(sDefaultExecutor, params);
}
private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
public final AsyncTask 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)");
}
}
//设置当前状态是running
mStatus = Status.RUNNING;
//调用onPreExecute();
onPreExecute();
mWorker.mParams = params;
exec.execute(mFuture);
return this;
}
SerialExecutor继承了Executor,并且使用ArrayDeque来保证了线程的顺序执行
private static class SerialExecutor implements Executor {
final ArrayDeque mTasks = new ArrayDeque();
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);
}
}
}
//THREAD_POOL_EXECUTOR定义
public static final Executor THREAD_POOL_EXECUTOR;
static {
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS,
sPoolWorkQueue, sThreadFactory);
threadPoolExecutor.allowCoreThreadTimeOut(true);
THREAD_POOL_EXECUTOR = threadPoolExecutor;
}
InternalHandler 处理与UI线程
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;
}
}
}
总结
- 1,AsyncTask 使用ThreadPoolExecutor 实现线程池来管理线程
- 2,AsyncTask的SerialExecutor使用 ArrayDeque
来保证顺序执行线程。 - 3,使用WorkerRunable和FutureTask来实现子线程和获得子线程的执行的结果。
- 4,使用Handler用于线程与主线程之间的通信和回调结果。
推荐阅读
- android第三方框架(五)ButterKnife
- Android中的AES加密-下
- 带有Hilt的Android上的依赖注入
- android|android studio中ndk的使用
- Android事件传递源码分析
- RxJava|RxJava 在Android项目中的使用(一)
- Android7.0|Android7.0 第三方应用无法访问私有库
- 深入理解|深入理解 Android 9.0 Crash 机制(二)
- android防止连续点击的简单实现(kotlin)
- Android|Android install 多个设备时指定设备