Android源码分析——广播

广播是一种在组件之间进行消息传递的方式。广播机制的实现是基于Binder进程间通信。

Binder进程间通信和广播的差别:Binder中,Client组件和Service组件通信之前必须先获得Service的一个代理对象,Client组件事先要知道Service组件的存在。广播发送者事先是不要知道广播接收者的存在。因此,广播发送者和接收者之间的耦合度较低

广播是基于消息发布和订阅者模型实现的。

在同等情况下,动态注册的广播接收者要比静态注册的广播接收者优先收到广播。

android.intent.action.SCREEN_OFF android.intent.action.SCREEN_ON,这两个类型的广播只能被动态注册的接收器处理

发送方如何指定该广播可以被谁接收:设置自定义权限。

广播接收者的注册过程

ContextWrapper.registerReceiver

ContextImpl. registerReceiver

ActivityManagerProxy.registerReceiver

ActivityManagerService.registerReceiver

广播的发送过程

广播发送主要过程:
  1. 广播发送者将一个广播发送给AMS。
  2. AMS接收到一个广播后,首先找到这个广播的接收者,然后将他们添加到一个广播调度队列中,最后向AMS所在的线程消息队列发送一个类型为BROADCAST_INTENT_MSG的消息。
  3. 当AMS所在线程消息队列中的BROADCAST_INTENT_MSG消息被处理时,AMS就会从广播调度队列中找到需要接收广播的广播接收者,并将对应的广播发送给他们所在的进程。
  4. 广播接收者所运行在的应用程序进程接收到AMS发送过来的广播之后,将广播封装成一个消息,并发送到主线程消息队列中。当该消息被处理时,应用程序进程才会将该广播发送给相应的广播接收者处理。

第1步——广播发送者将一个广播发送给AMS:

ContextWrapper.sendBroadcast

ContextImpl.sendBroadcast

ActivityManagerProxy.broadcaseIntent

ActivityManagerService. broadcaseIntent


第2步——查找目标广播接收者

ActivityInfo ai = AppGlobals.getPackageManager().getReceiverInfo(intent.getComponent,

STOCK_PM_FLAGS);

If(ai!=null){

Receivers = new ArrayList();

ResolveInfo ri = new ResolveInfo();

Ri.activityInfo = ai;

Receivers.add(ri);

}

AMS通过消息处理机制将广播转发给目标广播接收者。

AMS将广播(无序或有序)封装为一个广播转发任务,并添加到内部一个有序广播调度队列中。

动态注册广播接收者、静态注册广播接收者两个队列都是按照优先级从高到低的顺序来排列的。

if(curr.getPriority() >= curt.priority)说明如果一个动态注册的目标广播接收者和静态注册的广播接收者的优先级相同,动态注册的接收者排在前面,即先收到广播。

ActivityManagerService.scheduleBroadcastLocked发送一个类型为BROADCAST_INTENT_MSG消息。


第3步——处理AMS发送的消息

Handler.handleMessage

ActivityManagerService.processNextBroadcast

ActivityManagerService.deliverToRegisteredReceiverLocked

如果BroadcastFilter.requiredPermission的值不为null,那么就表示ActivityManagerService需要检查广播发送者的权限。

如果BroadcastRecord对象的成员变量requiredPermission的值不为null,表示AMS需要检查广播接收者的权限。

以上这两个权限是调用AMS成员函数checkComponentPermission来检查对方PID和UID是否符合要求。

ActivityManagerService.performReceiverLocked


第4步——广播接收者处理MSG

ApplicationThread.scheduleRegisteredReceiver

InnerReceiver.performReceive

ReceiverDispatcher.performReceive

Args.run

BroadcastReceiver.onReceive

Android源码——Broadcast Receiver的更多相关文章

  1. Android源码分析-全面理解Context

    前言 Context在android中的作用不言而喻,当我们访问当前应用的资源,启动一个新的activity的时候都需要提供Context,而这个Context到底是什么呢,这个问题好像很好回答又好像 ...

  2. 2014年最新720多套Android源码2.0GB免费一次性打包下载

    之前发过一个帖子,但是那个帖子有点问题我就重新发一个吧,下面的源码是我从今年3月份开始不断整理源码区和其他网站上的android源码,目前总共有720套左右,根据实现的功能被我分成了100多个类,总共 ...

  3. 阅读android源码了解 android 加载so的流程

    参考原文:http://bbs.pediy.com/thread-217656.htm Android安全–linker加载so流程,在.init下断点: http://www.blogfshare. ...

  4. Android源码分析(六)-----蓝牙Bluetooth源码目录分析

    一 :Bluetooth 的设置应用 packages\apps\Settings\src\com\android\settings\bluetooth* 蓝牙设置应用及设置参数,蓝牙状态,蓝牙设备等 ...

  5. Android源码阅读 – Zygote

    @Dlive 本文档: 使用的Android源码版本为:Android-4.4.3_r1 kitkat (源码下载: http://source.android.com/source/index.ht ...

  6. Eclipse与Android源码中ProGuard工具的使用

    由于工作需要,这两天和同事在研究android下面的ProGuard工具的使用,通过查看android官网对该工具的介绍以及网络上其它相关资料,再加上自己的亲手实践,算是有了一个基本了解.下面将自己的 ...

  7. Android 源码下载方法(Git 方式clone)

    Android源码对于Android开发者来说,迟早有一天你会用到的,所以就记录一下,分享给读者,希望对读者有用 这里需要使用到Git相关知识,不清楚的可以先阅读,了解的可以跳过 Git-Tortoi ...

  8. Android源码编译make的错误处理

    android源码下载:官方下载 或参考android源码下载方式 Android编译版本: PLATFORM_VERSION=4.0.1(最新Android 4.0.1) OS 操作系统平台: Li ...

  9. Atitit.反编译apk android源码以及防止反编译apk

    Atitit.反编译apk android源码以及防止反编译apk 1.1. Tool  apk逆向助手1 1.2. 二.使用dex2jar + jd-gui 得到apk的java源码1 1.3. 用 ...

随机推荐

  1. Jquery 页面间传值(非QuerryString)

    实现原理: 实现方式不是很复杂,父页面A打开一个子页面 A1,并同时写一个带参数的接收数据函数Receive(result),在A1页面进行逻辑操作,然后调用父页面A的Receive(result)函 ...

  2. jquery瀑布流的制作

    首先,还是来看一下炫酷的页面: 今天就边做边说了: 一.准备工作 新建css,js,img文件夹存放相应文件,并在demo.html文件中引入外部文件(注意要把jquery文件引入),这里就不过多描述 ...

  3. iOS开发之Bug(持续更新)

    前言:收集在开发和学习的过程中遇到的bug. 1.循环利用cell的ID设置位置写错了.导致程序奔溃. 2.对于除数算法,可以直接算出结果的就写上结果,不要偷懒写式子让计算机自己算,更何况是除数,会有 ...

  4. 了解npm的文件结构(npm-folders)和配置文件(npm-mrc)

    一.npm的文件结构 npm的安装: 本地安装 1. 将安装包放在 ./node_modules 下(运行 npm 命令时所在的目录),如果没有 node_modules 目录,会在当前执行 npm ...

  5. ps如何裁剪掉图片的不规则区域

    按P,鼠标变成钢笔工具,点选住待清除区域,如下: 按ctrl+enter, 将点线变成选中区域: 按delete删除: ctrl+D取消选中区域 完成!

  6. 原创 C++作用域 (二)

    2.3全局作用域 2.3.1概述 全局作用域是最大的名字空间作用域,不同于用户自定义的名字空间作用域,全局作用域不需要显示地定义,它天然存在于C++程序中.全局作用域是一个最外层的容器,是所有作用域的 ...

  7. JavaSe:ThreadLocal

    JDK中有一个ThreadLocal类,使用很方便,但是却很容易出现问题.究其原因, 就是对ThreadLocal理解不到位.最近项目中,出现了内存泄漏的问题.其中就有同事在使用ThreadLocal ...

  8. 从一道面试题来认识java类加载时机与过程

    说明:本文的内容是看了<深入理解Java虚拟机:JVM高级特性与最佳实践>后为加印象和理解,便记录了重要的内容. 1  开门见山 以前曾经看到过一个java的面试题,当时觉得此题很简单,可 ...

  9. iOS CALayer应用详解(2)

    参考博客:http://blog.csdn.net/hello_hwc?viewmode=list 如果你对CALayer 还没有一个清晰的理解,欢迎看一下前面的博客: http://www.cnbl ...

  10. codevs 1472 体检

    题目描述 Description 郑厂长不是正厂长 也不是副厂长 他根本就不是厂长 只是公司的一个码农 郑厂长所在的公司每一年都要组织员工体检,比如量身高体重.测血压之类的,今年也不例外. 这次总共有 ...