Android系统广播(Broadcast)注册,发送,接收流程解析

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android系统广播(Broadcast)注册,发送,接收流程解析相关的知识,希望对你有一定的参考价值。

参考技术A

以下广播简称Broadcast

   是android四大组件之一,在四大组件的另外两个组件 和 拥有发送和接收广播的能力。Android 是在 进程间通信机制的基础上实现的,内部基于消息发布和订阅的事件驱动模型,广播发送者负责发送消息,广播接收者需要先订阅消息,然后才能收到消息。 进程间通信与 的区别在于:

   有三种类型

   存在一个注册中心,也可以说是一个调度中心,即 。广播接收者将自己注册到 中,并指定要接收的广播类型;广播发送者发送广播时,发送的广播首先会发送到 , 根据广播的类型找到对应的 ,找到后边将广播发送给其处理。

   这里以普通广播为例子, 接收者有两种注册方式,一种是 ,一种是 :

(广播的发送分为 两种,这里针对有序的广播) 中的android:priority=""和 中的IntentFilter.setPriority(int)可以用来设置广播接收者的优先级,默认都是0 , 范围是[-1000, 1000],值越大优先级越高,优先级越高越早收到。

   在相同优先级接收同个类型广播时, 的广播接收器比 的广播接收者更快的接收到对应的广播,这个之后会进行分析。

   注:以下源码基于rk3399_industry Android7.1.2

   的流程可分为 , 和 三个部分,这里依次分析下

   在Android系统的 机制中,前面提到, 作为一个注册和调度中心负责注册和转发 。所以 的注册过程就是把它注册到 的过程。

   这里我们分析 广播的过程, 和 有一个共同的父类 ,所以它们对应的注册过程其实是调用 ,接下来我们按照流程逐步分析调用流程的源码。

frameworks/base/core/java/android/content/ContextWrapper.java

   在之前的 Android应用程序启动入口ActivityThread.main流程分析 分析过,在我们启动 Activity 时会创建一个 对象,然后通过 传给我们启动的 ,其内部就会将该对象赋值给 ; 的 方法也是类似的赋值流程,这里放个简易的源码应该更好理解

   可以看到最后都会将生成的 对象赋值给对应的
对象。接下来继续分析 , 即 函数。

/frameworks/base/core/java/android/app/ContextImpl.java

   这里我们首先看下如何将广播接收者 封装成一个 接口的 本地对象
/frameworks/base/core/java/android/app/LoadedApk.java

   每一个注册过广播接收者的 或 组件在<font color=\'Crimson\'> LoadedApk </font>类中都有个对应的 对象,该对象负责将 与 组件关联起来。这些对象,以关联的 作为关键字保存在一个 中。之后对应的 又以 的 作为关键字保存在 的成员变量 对象中。最后通过 对应的 方法获得其 接口的 本地对象。之后再回到 注册方法内,将 对象发给 进行注册。

/frameworks/base/core/java/android/app/ActivityManagerNative.java

/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

   在的 或 注册一个 时,并不是将其注册到<font color=\'OrangeRed\'>AMS</font>中,而是将与它关联的<font color=\'OrangeRed\'>InnerReceiver</font>对象注册到<font color=\'OrangeRed\'>AMS</font>中,当<font color=\'OrangeRed\'>AMS</font>接收到广播时,会根据 在内部找到对应的<font color=\'OrangeRed\'>InnerReceiver</font>对象,然后在通过这个对象将这个广播发送给对应的 处理。

   注册过程这边画了一个简单的流程图:

   <font color=\'OrangeRed\'>Broadcast</font>的发送过程可简单描述为以下几个过程:

frameworks/base/core/java/android/content/ContextWrapper.java

/frameworks/base/core/java/android/app/ContextImpl.java

/frameworks/base/core/java/android/app/ActivityManagerNative.java

/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

广播Broadcast Receiver

广播的类型:

1、标准广播(Normal broadcat)

  完全异步执行的广播,所有广播接收器同一时间接收广播消息。

  效率高,但无法被截断。

2、有序广播

  同步执行的广播,同一时刻只能有一个广播接收器接收广播消息,当执行完毕后才会继续传递。

  优先级高的先收到广播,并且可以截断广播。

接收系统广播:

  注册:动态注册(代码)和静态注册(AndroidaManifest.xml)

动态广播:

  1、继承Broadcastreceiver

  2、重写onReceive()方法

  3、注册registerReceiver()

  4、动态注册的广播接收器一定要取消注册,unregisterReceiver()

  5、声明权限在AndroidManifest.xml中

静态广播接收器在AndroidManifest.xml中通过<receiver>标签进行注册,

<receiver android:name=".BootCompleteReceiver ">
  <intetn-filter>
    <action android:name="android.intent.action.BOOT_COMPLETED">   //开机广播
  </intent-filter>
</recevier>

  广播接收器中不允许开启线程,不要添加过多逻辑或进行任何耗时操作。

自定义广播:

  1、标准广播:

  (1)定义一个广播接收器

  (2)在事件里加入自定义广播的逻辑

  (3)构建Intent对象,传入要发送的广播的值

  (4)调用sendBroadcast()方法,发送广播

  (5)在AndroidManifest.xml中<receiver>注册

  2、有序广播:

  基本与标准广播一样,发送调用sendOrderedBroadcast()方法。

  在AndroidManifest.xml中设置优先级<intent-filter android:priority="100">

  截断广播调用abortBroadcast()方法

本地广播:(解决安全性问题)

  使用LocalBroadcastManager对广播进行管理。

  (1)通过LocalBroadcastManager.getInstance(this)获取他的实例

  (2)构建LocalReceiver类

  (3)通过LocalBroadcastManager的registerReceiver()方法进行动态注册。方法中包含2个参数localReceiver和intentfilter

  (4)调用LocalBroadcastManager的sendBroadcast()方法进行发送广播

  (5)在onDestroy()方法中取消注册

  本地广播无法使用静态注册的方式来接收。

 

以上是关于Android系统广播(Broadcast)注册,发送,接收流程解析的主要内容,如果未能解决你的问题,请参考以下文章

详解广播机制,Broadcast Receiver,Android进阶必备知识。

Android安全笔记-Broadcast基本概念

详解广播机制,Broadcast Receiver,Android进阶必备知识。

Android App开发超实用实例 | ​Broadcast

广播 Broadcast Receiver

android Broadcast广播消息代码实现