之前在进行Android开发的过程中,由于某些原因,对android中广播的注册等相关知识进行了回顾及总结。也查看了相关源码及写demo验证。发现对广播的认识更深了一层。下面将所学进行记录,以备随时查看。
这些内容在网上也参考了他人的博客,相关链接如下:
【1】、基于源码分析的系统发送广播的流程:http://blog.csdn.net/zhangyongfeiyong/article/details/52022935 (很详细,推荐)
【2】、静态注册无法接收广播的问题:http://blog.csdn.net/ocean2006/article/details/40806819
源码路径:frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java
广播的发送过程比广播的注册过程复杂的多,主要有以下几个步骤:(摘自上述【1】)
1.广播的发送者将一个特定类型的广播发送给ActivityManagerService。
2.AMS接收到这个广播后,首先找到与这个广播对应的广播接收者,然后将它们添加到一个广播调度队列中,再将这个调度队列传递给BroadcastQueue,最后向BroadcastQueue的消息队列发送一个类型为BROADCAST_INTENT_MSG的消息,此时对于广播发送者来说,一个广播的发送就完成了。
3.当消息队列中的BROADCAST_INTENT_MSG消息被处理时,BroadcastQueue就会从广播调度队列中找到需要接收广播的接收者,并且将对应的广播发送给它们所运行在的应用程序进程。
4.广播接收者所运行在的应用程序进程接收到广播后,并不是直接将接收到的广播分发给各个广播接收者来处理,而是将接收到的广播封装成一个消息,并且发送到主线程的消息队列中。当这个消息被处理时,应用程序进程才会将它所描述的广播发送给相应的广播接收者处理。
对于源码可主要查看ActivityManagerService中的broadcastIntentLocked():用于查找目标广播接收者。
注:从Android3.1以后,由于AMS中添加了FLAG_EXCLUDE_STOPPED_PACKAGES标志,导致静态注册的广播接收者在程序从未启动过时,不会再接收到广播。(已验证)
关于Intent中下述两个标志的说明:
Intent.FLAG_INCLUDE_STOPPED_PACKAGES:即使程序从未启动过,设置该标志后,该广播也可以被静态注册的广播接收。
Intent.FLAG_EXCLUDE_STOPPED_PACKAGES:(AMS默认设置)与上述相反.值得注意的是,系统应用不受此标志的影响。(例:push到system/app下的应用,即使从未启动过,静态注册的广播接收者也可以收到广播)
另外需要注意的一点:动态广播需要主动销毁(unregister),否则易引起内存泄露。而其作用范围,依赖于注册其的Activity,应用关闭或注销广播则会结束。静态则会常驻,无论应用程序是否关闭,都能收到广播(除了上述所说的程序从未启动过的情况)。
最后附上两个其他的实际应用广播的链接:
1、应用中监听SD卡的插拔:http://blog.csdn.net/a443453087/article/details/8085555
----注册时不要忘记写
2、Android中关于BroadcastReceiver使用的基础+全面介绍:https://www.jianshu.com/p/ca3d87a4cdf3
关于应用中如何获取设备外置存储路径的方法,请看我另一篇博客:Android获取外置存储路径
声明:有任何问题或侵犯了上述引用博客的地方请留言,谢谢!