Android的BroadcastReceiver

embedded/2024/11/14 6:36:28/

1.基本概念:BroadCast用于进程间或者线程间通信

本质上是用Binder方法,以AMS为订阅中心,完成注册,发布,监听的操作。

2.简单实现的例子

package com.android.car.myapplication;import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.widget.Toast;import androidx.appcompat.app.AppCompatActivity;public class MainActivityBroadCast extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_carsetting);//系统广播IntentFilter intentFilter = new IntentFilter();intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);BatteryReceiver batteryReceiver = new BatteryReceiver();registerReceiver(batteryReceiver,intentFilter);}public class BatteryReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {Bundle bundle = intent.getExtras();int current = bundle.getInt("level");int total = bundle.getInt("scale");if(current * 1.0 / total ==1){System.out.println("当前手机电量为"+(current / total)*100+"%");}}}
}

用法很简单不多赘述。

3.接收端registerReceiver

ContextImp:Context的最终实现类。class ContextImpl extends Context

  • ContextImpl.registerReceiver方法:
。。。。。。//注册binder应用和action到系统
final Intent intent = ActivityManager.getService().registerReceiver(mMainThread.getApplicationThread(), mBasePackageName, rd,filter,...);
  • ActivityManager中getService()实际上是一个Binder
    在ActivityManager.java中可看到:
public static IActivityManager getService() {return IActivityManagerSingleton.get();}private static final Singleton<IActivityManager> IActivityManagerSingleton =new Singleton<IActivityManager>() {@Overrideprotected IActivityManager create() {final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);final IActivityManager am = IActivityManager.Stub.asInterface(b);return am;}};}
  • 所以registerReceiver最后是一个向ActivityManagerService的Binder调用,只不过设计上加上了的发布订阅模式

4.发送端 sendBroadcast

  • 首先调用context的sendBroadCast方法
// Context.javapublic abstract void sendBroadcast(@RequiresPermission Intent intent);
  • 调到实现类ContextImpl
// ContextImpl.java(extents Context.java)@Overridepublic void sendBroadcast(Intent intent) {warnIfCallingFromSystemProcess();String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());try {intent.prepareToLeaveProcess(this);ActivityManager.getService().broadcastIntent(mMainThread.getApplicationThread(), intent, resolvedType, null,Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, false,getUserId());} catch (RemoteException e) {throw e.rethrowFromSystemServer();}}
  • 同理调用到ActivityManagerService的broadcastIntent方法。

(AMS中关于发布订阅的实现,不在本文范围之内,后续遇到问题再继续研究)

5.总结

如果了解发布订阅的设计模式
了解发布,订阅,订阅中心的模型,那么BroadCastReceiver的基本实现原理就清楚了。

  • 接收端首先订阅,即调用Binder方法registerReceiver。
  • AMS会记下对这个Intent感兴趣的进程
  • 发送端通过Binder方法sendBroadCast发送一个Intent。
  • AMS会收到Intent消息
  • AMS找到所有对Intent消息感兴趣的接收端,将这个消息发到接收端
  • 接收端进入实现的onReceive方法。

参考图:https://www.cnblogs.com/andy-songwei/p/10400259.html
在这里插入图片描述收到


http://www.ppmy.cn/embedded/136990.html

相关文章

如何选择适合你的显示器:关键指标解析

文章目录 前言1. 屏幕尺寸&#xff1a;决定观看舒适度2. 分辨率&#xff1a;影响显示效果的关键3. 刷新率&#xff1a;提升视觉流畅度4. 响应时间&#xff1a;减少画面延迟5. 面板类型&#xff1a;影响色彩与视角6. 接口与兼容性&#xff1a;确保多设备连接7. 可调性与人体工学…

学习python的第八天之数据类型——list列表

学习python的第八天之数据类型——list列表 Python 中的列表&#xff08;list&#xff09;是一种基本的数据结构&#xff0c;它可以包含零个或多个元素&#xff0c;这些元素可以是不同类型的。列表是可变的&#xff08;mutable&#xff09;&#xff0c;这意味着我们可以在创建列…

【go从零单排】Closing Channels通道关闭、Range over Channels

&#x1f308;Don’t worry , just coding! 内耗与overthinking只会削弱你的精力&#xff0c;虚度你的光阴&#xff0c;每天迈出一小步&#xff0c;回头时发现已经走了很远。 &#x1f4d7;概念 在 Go 语言中&#xff0c;通道&#xff08;channel&#xff09;的关闭是一个重要…

C++ 错题本--duplicate symbol问题

顾名思义, duplicate symbol是重复符号的意思! 代码是用来做什么的(问题缘由 & 代码结构) 写排序算法, 提出了一个公共的头文件用来写一些工具方法, 比如打印数组内容. 以便于不同文件代码需要打印数组内容的时候,直接引入相关头文件即可, 但是编译时出现了 duplicate sym…

组件间通信(组件间传递数据)

组件间通信(组件间传递数据) 在 Vue.js 中&#xff0c;组件间通信是开发者需要经常处理的任务&#xff0c;特别是在构建具有多层次组件的复杂应用时。根据组件之间的关系和数据流的复杂程度&#xff0c;可以采用不同的通信方式。以下是常用的几种组件间通信方式&#xff1a; …

MacBook 下载vscode不能被解压及打开的解决方案

mac 下载vscode不能被解压解决方案如下 1.下载全能解压 进行解压 解压完如果提示 已损坏&#xff0c;无法打开。 您应该将它移到废纸篓 2.允许“任何来源”开启 开启终端输入 sudo spctl --master-disable回车 3. 扩展文件属性 先输入 sudo xattr -r -d com.apple.quaran…

C#核心(8) 静态成员

前言 先前我们已经学习了成员变量以及成员属性。 静态成员对于在整个应用程序中共享数据和功能非常有用。它们可以用于跟踪全局状态、共享常量和实现单例模式等。但是需要注意的是&#xff0c;过度使用静态成员可能导致代码变得难以维护和测试&#xff0c;因此应谨慎使用。其…

深⼊理解指针(5)[回调函数、qsort相关知识(qsort可用于各种类型变量的排序)】

目录 1. 回调函数 2. qsort相关知识&#xff08;qsort可用于各种类型变量的排序&#xff09; 一 回调函数 1定义/作用:把函数的指针&#xff08;地址&#xff09;作为参数传递给另⼀个函数&#xff0c;当这个指针被⽤来调⽤其所指向的函数 时&#xff0c;被调⽤的函数就…