AsyncTask工作原理复习总结
上周闲来无事就去某些大公司面试了一下,试试现在android这块的水!总结出结论就是,稍大点的公司问的基础的东西还是比较的多,而规模较小的公司则是更注重模块功能点的实现!所以呢,你未来职业的发展得有个大体的规划,大公司呢,就多注意一下基础知识和整体框架的把握,而规模稍小的公司则需要你将某些功能块挖的深一些!这是我个人的感觉,哈哈!仅供参考!
进入正题!
AsyncTask已经出来太久了,以至于我们可以很熟悉的用它!那它是怎么工作的呢?之前在学习android的时候,看过它的源码实现!但是实在太久了,差不多都忘光了!今天早上手上的事情做完后无聊,就又走了一遍,突然感觉看别人的源码比自己撸代码还要舒服!
这里写图片描述我们先从实例化AsyncTask开始逐步了解!
这里写图片描述OK,我们聊一下这张图!从WorkerRunnable中我们看到了AsyncTask的一个重要方法doInBackfround()是在这个方法中执行的!然后再将WorkerRunnable的引用添加到了FutureTask中执行结果回调。所以说基本可以确定这是在子线程中的,当然还有一行代码可以证明:
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
这行代码什么意思呢?
这里写图片描述标准后台线程。这让你的线程低于正常的优先级,这样会保证用户界面的响应性。
OK,看到这即可了!我们不能盲目的钻到理解代码的详细细节上,不然就出不去了!
AsyncTask实例化完了,我们就改看看他是怎么执行的吧!执行的话,我们通常会调用它的execute()方法。
这里写图片描述嗯,知识简单的执行了一个函数,并传入了两个参数!sDefaultExecutor和params,第二个参数,不用说了,就是我们自己传入的参数,第一个呢?
这里写图片描述嗯,它是SerialExecutor的实例化对象,实现了Executor,重要的是下面这行代码:
final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
SerialExecutor通过ArrayDeque控制管理线程池中的Runnable对象,其原理是队列,先进先出形式!
看看它提供的offer方法:
这里写图片描述很简单的翻译吧!在队未添加一个Runnable元素。
再看poll方法:
这里写图片描述
取出并移除顶部元素
嗯,大概明白了!SerialExecutor是一个线程池,它通过ArrayDeque来控制线程Runnable的执行顺序!也就是说SerialExecutor是一个排队的线程池!
接着说executeOnExecutor(),它将SerialExecutor和params(我们自己设置的参数)传过去了!
这里写图片描述哈哈,是不是看到了执行流程了?
Pending(等待)-->Running(运行)-->Finished(结束)
如果非等待状态,那就不好意思了!抛出了异常!
如果是等待状态则执行:
mStatus更改为RUNNING状态;
onPreExecute();执行之前预备状态
mWorker.mParams = params;设置传过来的参数
exec.execute(mFuture);开始执行
exec则是我们传过来的SerialExecutor,而mFuture则是我们在实例化的时候生成的子线容器!
回过头再看SerialExecutor
这里写图片描述在执行 r.run()后,我们怎么获得执行的结果呢?
这里写图片描述FutureTask执行完成后必会调用
protected void done()
那就会执行postResultIfNotInvoked(get());
接着
再接着实例化Handler;
这里写图片描述Handler发送消息进行处理:
这里写图片描述这个主意的是,在super(Looper.getMainLooper());执行后,又回到到了主线程!而在执行finish方法的时候,调用了onPostExecute(result);使得结果得到了回调成功!
这里写图片描述OK,执行流程大概就是这么个样子!
总结:
总的来说AsyncTask的内部封装了SERIAL_EXECUTOR(排队线程池),THREAD_POOL_EXECUTOR(执行线程池),以WorkerRunnable为子线程封装可回调控制操作的FutureTask子线程,以及用于更新界面的一个内部InternalHandler,这么一个结构,理解起来并不是很难!关键是人家的这种设计和一些api的合理使用!
闲话少说,年关了,估计大伙都蠢蠢欲动!加油吧!
每天进步一点点,时间会让你成为巨人!