Android BroadcastReceiver 工作过程

BroadcastReceiver 工作过程

主要分为两个部分:广播注册、广播发送/接收

简单回顾广播使用方法
先定义广播接收者

public class MyReceiver extends BroadcastReceiver{
  @Override
  public void onReceive(Context context,Intent intent){
     String action = intent.getAction();
     // do some works
  }
}

接着注册广播接受者(静态)

<receiver android:name = ".MyReceiver">
   <intent-filter>
       <action android:name = "com.ryg.receiver.LAUNCH">
   </intent-filter>
</receiver>

动态注册

IntentFilter filter = new IntentFilter();
filter.addAction("com.ryg.receiver.LAUNCH");
registerReceiver(new MyReceiver(),filter);

发送广播

Intent intent = new Intent();
intent.setAction("com.ryg.receiver.LAUNCH");
sendBrodcast(intent);

BroadcastReceiver注册过程

静态广播在应用安装时由系统自动完成注册,具体来说是由PMS(Package Manager Service)来完成注册过程的。另外三大组件也是如此。

而动态注册过程是从ContextWrapper的registerReceiver方法开始,和Activity以及Service一样。
而ContextWrapper将注册交给了ContextImpl来完成。
在这里插入图片描述
而ContextImpl的registerReceiver又调用了registerReceiverInternal
在这里插入图片描述
从mPackgeInfo获取IIntentReceiver对象,然后再采用跨进程的方式向AMS发送广播注册请求。之所以使用IIntentReceiver对象,而不是BroadcastReceiver。

因为这个注册过程是进程间通信的过程,而BroadcastReceiver不能直接跨进程传递,需要依赖IIntentReceiver来中转一下。

而IIntentReceiver必须是个Binder接口,其具体实现是LoadedApk.ReceiverDispatcher.
InnerReceiver。

而ReceiverDispatcher的内部同时保存了BroadcastReceiver和InnerReceiver,使得当ReceiverDispatcher收到广播后,可以调用BroadcastReceiver的onReceive。
在这里插入图片描述
ReceiverDispatcher 的getReceiverDispatcher 在上面的代码中被调用了,getReceiverDispatcher重新创建了一个ReceiverDispatcher,并返回其保存的InnerReceiver
在这里插入图片描述
注册广播的主要实现在AMS中,即ActivityManagerNative,保存远程的InnerRecevier和IntentFilter。
在这里插入图片描述
在这里插入图片描述

广播的发送和接收

广播的发送和接收本质是一个过程的两个阶段。

广播的发送仍然开始于ContextWrapper的sendBroadcast方法,之所以不是Context,是因为Context的sendBroadcast是一个抽象方法。和广播注册过程一样,ContextWrapper的sendBroadcast将事情交给ContextImpl去处理,而ContextImpl直接对AMS发起了异步请求。
在这里插入图片描述
调用的broadcastIntent,其中关键是调用了broadcastIntentLocked。
在这里插入图片描述

//表明广播是否要对处于停止状态的应用起作用。
//FLAG_EXCLUDE_STOPPED_PACKAGES和EXCLUDE_STOPPED_PACKAGES
intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKGES)

broadcastIntentLocked内部会根据intent-filter查找出匹配的广播接收者并经过一系列的条件过滤,最终会将满足条件的广播接收者添加到BroadcastQueue中,接着BroadcastQueue就会将广播发送给相应的广播接收者。

在这里插入图片描述在这里插入图片描述

broadcastIntentLocked在将广播接收者加入queue后,还调用了BroadcastQueue的scheduleBroadcastsLocked。但scheduleBroadcastsLocked也不是立刻发送广播,他发送了一个BROADCAST_INTENT_MSG类型消息,BroadcastQueue收到消息后会调processNextBroadcast方法。
在这里插入图片描述
processNextBroadcas:
系统遍历存储着无序广播的mParallelBroadcasts,并将其中的广播发送给它们所有的接收者,而这个发送过程由performReceiveLocked方法来完成,它负责将一个广播发送给一个特定的接收者。
在这里插入图片描述
在这里插入图片描述
performReceiveLocked如下,主要是通过app.thread调起应用程序接受广播
在这里插入图片描述

ApplicationThread的scheduleRegisteredReceiver通过InnerReceiver的performReceive实现广播接收。

创建了一个Args对象并通过mActivityThread的post方法来执行Args中的逻辑,而Args实现了Runnable接口。mActivityThread是一个handler,它其实就是ActivityThread的内部类H类型mH。
在这里插入图片描述
Args的run方法中有这几行代码:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值