写点什么

Android 开发艺术探索笔记(21)

用户头像
Android架构
关注
发布于: 2021 年 11 月 07 日


loop 是一个死循环,唯一跳出循环的方式是 MessageQueue 的 next 方法是 null。当没有消息时,next 会一直阻塞,导致 loop 也一直阻塞。如果 next 返回了新消息,则用 dispatchMessage 去处理,而这个方法是在创建它 Handler 的 Looper 中执行的,这样就成功的将代码逻辑切换到指定的线程中去了。


Handler 的工作原理


Handler 的主要作用是发送和接收过程。post 最终也是通过 send 来实现的,sendMessage 的源码就是在 MessageQueue 中添加一条信息,然后 MessageQueue 就会通过 next 将这条信息交给 Looper,最后由 Looper 交由 Handler 处理,即调用了 Handler 的 dispatchMessage。


dispatchMessage 先检查 msg 的 callback 是否为 null,不为 null 就通过 handleCallback 来处理信息。Message 的 callback 是一个 Runnable 对象,实际上就是 Handler 的 post 方法所传递的 Runnable 参数。handleCallback 的逻辑就是运行这个 Runnable。接着检查 mCallback 是否为 null,不为 null 就调用 mCallback 的 HandleMessage 方法来处理消息。最后通过 Handler 的 HandleMessage 来处理消息。整个过程如下流程图:


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码



主线程的消息循环:


ActivityThread 通过 ApplicationThread 和 AMS 来进行 IPC,AMS 以进程间通信的方式完成 ActivityThread 的请求后会回调 ApplicationThread 的 Binder 方法,然后 ApplicationThread 会向 H 发出信息,H 收到消息后会将 ApplicationThread 的逻辑切换到 ActivityThread 中去执行,即切换到主线程中执行。这个过程就是主线程的消息循环模型。


Android 的线程和线程池




在 Android 中,除了 Thread 可以扮演线程,AsyncTask、HandlerThread 和 IntentService。


线程池缓存了一定数量的线程,可以避免频繁的创建和销毁线程所带来的系统开销。主要通过 Executor 来派生特定类型的线程池。


AsyncTask


AsyncTask 是一个轻量级的异步任务类,它可以在线程池中执行任务,然后将结果传递给主线程更新 UI。AsyncTask 封装了 Handler 和 Thread。但它并不适合特别耗时的线程操作。


AsyncTask 是一个抽象泛型类,它提供了 Params、Progress、Result 三个泛型参数。Params 表示参数的类型,Progress 表示后台执行任务的进度、Result 表示后台任务返回结果的类型。它有 4 个核心方法:


(1)onPreExecute(),在主线程中执行,做准备工作。


(2)doInBackground(Params…params),在线程池中执行,执行异步任务,参数列表为输入参数,在这个方法中可以用 publishProgress 方法来更新任务的进度,publishProgress 会调用 onProgressUpdate 方法。此方法需要返回计算结果回 onPostExecute。


(3)onProgressUpdate,在主线程进行。后台任务进度改变后此方法调用。


(4)onPostExecute(Result result),在主线程运行。


还有 onCancelled 方法,在主线程进行,当异步任务取消时,此方法调用,onPostExecute 方法不会被调用。


使用 AsynceTask 只需创建一个内部类来继承 AsynceTask 然后重写上述方法就行了,然后将这个类实例化并执行 execute 方法就 OK。


AsyncTask 的使用条件:


(1)必须使用在主线程


(2)其对象必须在主线程中创建


(3)execute 必须在 UI 线程中调用


(4)不要在程序中直接调用那 4 个核心方法


(5)一个 AsyncTask 对象只能使用一次,即只能调用一次 execute 方法,否则会报错。


(6)我们可以使用 AsyncTask 的 executeOnExecutor 方法来并行的执行任务。

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
Android 开发艺术探索笔记(21)