Android(安卓)AsyncTask源码解析
Android AsyncTask源码解析
AsyncTask是一个google为开发者提供的一个实现的一个轻量级的类库。
AsyncTask是一个虚类,所以我们必须实现其中的doInBackground()方法。
初始话的时候需要实现如下的泛型方法。
public abstract class AsyncTask
Params表示用于AsyncTask执行任务的参数的类型
Progress表示在后台线程处理的过程中,可以阶段性地发布结果的数据类型
Result表示任务全部完成后所返回的数据类型
一个完整的AsyncTask使用流程如下。
private class MyTask extends AsyncTask { @Override protected void onPreExecute() { //在执行方法前的操作 } @Override protected Long doInBackground(String... params) { //这里用来进行操作异步请求的内容 } @Override protected void onProgressUpdate(Object... values) { //需要进行更新的内容,通过在 doInBackground中执行publishProgress();进行更新 } @Override protected void onPostExecute(Long aLong) { //在doInBackground执行完毕过后执行,用于执行回调回主线程的操作 } @Override protected void onCancelled() { } }
通过在代码中传入参数Params,执行代码。
MyTask myTask=new MyTask(); myTask.execute(Params);
既然是分析源码,那么我们还是从execute方法说着走。
@MainThread public final AsyncTask<Params, Progress, Result> execute(Params... params) { return executeOnExecutor(sDefaultExecutor, params); }
execute会到executeOnExecutor()方法中,这里将sDefaultExecutor线程池传入,同时将参数params传入。
sDefaultExecutor是个什么线程池?来到sDefaultExecutor的定义的地方。
public static final Executor SERIAL_EXECUTOR = new SerialExecutor(); private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
可以看到sDefaultExecutor就是new SerialExecutor();
SerialExecutor()又是什么?
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); } } }
可以看到SerialExecutor 实现了Executor 接口,当我们执行sDefaultExshecutor .excute()方法的时候,实际上也就是执行的上诉的excute()方法,可以看到这里新建了一个线程将我们的Runnable r进行了包装执行,执行完了过后才会执行scheduleNext()方法,scheduleNext()方法其实就是从mTasks中取出了方法,同时放入THREAD_POOL_EXECUTOR中执行。
THREAD_POOL_EXECUTOR又是什么?
private static final BlockingQueue sPoolWorkQueue =new LinkedBlockingQueue(128);private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors(); //当前可用的资源private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4)); //核心线程数2-4 private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1; //最大线程数为当前的可用资源*2+1static { ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor( CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory); //可以看到实际就是自定义了一个线程池,其中sPoolWorkQueue是长度为128的阻塞队列 。 threadPoolExecutor.allowCoreThreadTimeOut(true); THREAD_POOL_EXECUTOR = threadPoolExecutor; }
可以看到静态代码 块中对其进行了初始化。
@MainThread 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)"); } } mStatus = Status.RUNNING; onPreExecute(); mWorker.mParams = params; exec.execute(mFuture); return this; }
回到executeOnExecutor,可以看到这里首先执行了onPreExecute()方法。同时将params传入mworks。
private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> { Params[] mParams; }
mworks实际就是一个Callable接口。mfuture又是什么,看到了Callable首先就猜测,mFuture对mworks进行了包装,然后传入exec线程中进行执行。
果然在构造函数的地方可以看到
public AsyncTask(@Nullable Looper callbackLooper) { mHandler = callbackLooper == null || callbackLooper == Looper.getMainLooper() ? getMainHandler() : new Handler(callbackLooper); mWorker = new WorkerRunnable() { 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(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); } } }; }
可以看到mFuture 对mworker进行了包装同时执行了exec.excute()实际上也就是将mfuture包装成runable传入执行,实际执行的就是mWorker的call方法,在上面的代码中,通过result = doInBackground(mParams)执行了doInBackground,同时得到了结果。最后执行了postResult()方法。
private Result postResult(Result result) { @SuppressWarnings("unchecked") Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT, //发送MESSAGE_POST_RESULT信息 new AsyncTaskResult(this, result)); message.sendToTarget(); return 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: //收到了调用finish()函数 // There is only one result result.mTask.finish(result.mData[0]); break; case MESSAGE_POST_PROGRESS: result.mTask.onProgressUpdate(result.mData); //收到了更新函数. break; } } }
在finish中,可以看到会执行onPostExecute()方法,完成请求完成过后的回调。
private void finish(Result result) { if (isCancelled()) { onCancelled(result); } else { onPostExecute(result); } mStatus = Status.FINISHED; }
一个完整 的请求流程就是这样。
更多相关文章
- SpringBoot 2.0 中 HikariCP 数据库连接池原理解析
- Android(安卓)JS交互与JS代码注入--详解
- Android中保存Activity的状态
- [置顶] android scrollview 滑动到顶端或者指定位置
- Android之MainActivity类
- android四大组件启动流程-BroadcastReceiver启动流程(基于androi
- 在Eclipse中查看android 源代码的方法!
- 代码方法android全屏显示
- Android实时监控项目第四篇:后台线程发送预览帧视频数据