几乎每个安卓应用都无可避免的使用到广播。例如监听WIFI的开启状态、时间的获取,甚至是我们最常用的闹钟功能,都是结合着AlarmManager与广播来实现的。理解广播的注册、发送与接收实现源码将使我们更加懂安卓系统,同时,基于对广播的理解,我们也能很快的掌握AMS中其它组件的实现原理。
网上对于广播源码的分析数以千计,其中不乏精品的文章。但这些文章大多都太过枯燥、太抽象、太冗长,我最初看这些文章时,看了很多遍后才能慢慢理解。这篇文章里,我将画出几张简明扼要的图,简略的列出广播注册、发送中涉及到重要类。每副图后都会有我的一些简洁的理解,都是我在平日里开发中积累的精华。初学者能够通过这些对广播源码有个迅速的大体印象,熟悉广播源码的同学也能够查漏补缺。受语言与我自己理解的局限,如果文章中出现错误还希望大家指正。
文章最后,我会附上一张广播实用adb日志的输出对应图,希望能帮大家对于广播日志有个cheat sheet的作用:-)
我这张图为了避免信息太多内容晦涩,有两个重要的过程没有画出来:
这里我详细说说动态注册时,对sticky的特殊处理。
动态广播注册阶段中,第一步就是对sticky广播进行检查。 如果AMS中的mStickyBroadcasts存在符合过滤条件的Intent,那么这个广播在注册阶段就会被派发。当从registerReceiver传参进来的receiver为NULL,那么这个最新的sticky Intent将直接被返回。值得注意的一点是,在注册阶段发送出的广播是不会出现在dump日志历史记录中的。
再看这张图, 我将从左到右对每个重要图像进行解释:
mRegisteredReceivers中的数据在App进程死亡或App调用unregisterReceiver反注册接口才会被清除。
广播入队的过程中,最重要的步骤就是收集接收者的列表,并将它封装成一个BroadastRecord对象,将这个record对象加入到BroadcastQueue中,并调用Handler的sendMessage方法,准备派发广播
这张图中的BroadcastQueue, BroadcastRecord, BroadcastFilter, ResolveInfo和ReceiveList在前面的队列中都已经出现过了,我就不做解释了,只对App端的几个对象进行解释:
广播的派发是在BroadcastQueue对象中进行的,它维护着并行与串行两个队列。在派发的过程中,并行广播将会被先派发,随后再派发串行广播
动态广播的派发是取出BroadcastFilter的ReceiverList对象,通过ProcessRecord拿到ApplicationThread的代理对象,binder call调用,随后在App中调用BroadcastReceiver.onReceive方法;静态广播的派发是从ResolverInfo对象中取出processName, 再取出ProcessRecord, 最后在LoadedApk中调用了BroadcastReceiver.onReceive
这里我不想直接贴上这条adb命令的执行样例,因为实在太长了,会让这篇文章显得很水:-)
有兴趣的话大家可以试试这条命令,对应着我画的这个图,就能很清楚明白的理解它的意思
这里我简单解释下:
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有