当前位置: 首页 > news >正文

Android 广播 - 显式广播与隐式广播

测试引入

1、Receiver
publicclassExplicitAndImplicitReceiverextendsBroadcastReceiver{publicstaticfinalStringTAG=ExplicitAndImplicitReceiver.class.getSimpleName();publicstaticfinalStringACTION="broadcast.ExplicitAndImplicitReceiver";@OverridepublicvoidonReceive(Contextcontext,Intentintent){Log.i(TAG,"onReceive start");if(intent==null){Log.i(TAG,"intent is null");return;}Stringaction=intent.getAction();if(action==null){Log.i(TAG,"action is null");return;}if(!action.equals(ACTION)){Log.i(TAG,"action is not "+ACTION);return;}Log.i(TAG,"onReceive finish");}}
2、Activity
  • activity_explicit_and_implicit_receiver_test.xml
<?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:id="@+id/main"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".ExplicitAndImplicitReceiverTestActivity"><Buttonandroid:id="@+id/btn_send_explicit_broadcast"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="发送显式广播"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"/><Buttonandroid:id="@+id/btn_send_implicit_broadcast"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="发送隐式广播"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@+id/btn_send_explicit_broadcast"/></androidx.constraintlayout.widget.ConstraintLayout>
  • ExplicitAndImplicitReceiverTestActivity.java
publicclassExplicitAndImplicitReceiverTestActivityextendsAppCompatActivity{publicstaticfinalStringTAG=ExplicitAndImplicitReceiverTestActivity.class.getSimpleName();privateButtonbtnSendExplicitBroadcast;privateButtonbtnSendImplicitBroadcast;@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);EdgeToEdge.enable(this);setContentView(R.layout.activity_explicit_and_implicit_receiver_test);ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main),(v,insets)->{InsetssystemBars=insets.getInsets(WindowInsetsCompat.Type.systemBars());v.setPadding(systemBars.left,systemBars.top,systemBars.right,systemBars.bottom);returninsets;});btnSendExplicitBroadcast=findViewById(R.id.btn_send_explicit_broadcast);btnSendImplicitBroadcast=findViewById(R.id.btn_send_implicit_broadcast);btnSendExplicitBroadcast.setOnClickListener(v->{Log.i(TAG,"发送显式广播");Intentintent=newIntent(this,ExplicitAndImplicitReceiver.class);sendBroadcast(intent);});btnSendImplicitBroadcast.setOnClickListener(v->{Log.i(TAG,"发送隐式广播");Intentintent=newIntent(ExplicitAndImplicitReceiver.ACTION);sendBroadcast(intent);});}}
3、Test
(1)不声明 receiver
  1. 发送显式广播,输出结果
发送显式广播
  1. 发送隐式广播,输出结果
发送隐式广播
(2)声明 receiver,不声明 intent-filter
<receiverandroid:name=".mybroadcast.ExplicitAndImplicitReceiver"android:exported="false"/>
  1. 发送显式广播,输出结果
发送显式广播 onReceive start action is null
  1. 发送隐式广播,输出结果
发送隐式广播
(3)声明 receiver,声明 intent-filter(匹配的 action)
  1. 发送显式广播,输出结果
发送显式广播 onReceive start action is null
  1. 发送隐式广播,输出结果
# 理想情况 发送隐式广播 onReceive start onReceive finish
# 实际情况 发送隐式广播
(4)声明 receiver,声明 intent-filter(不匹配的 action)
  1. 发送显式广播,输出结果
发送显式广播 onReceive start action is null
  1. 发送隐式广播,输出结果
# 理想情况 发送隐式广播 onReceive start action is not broadcast.ExplicitAndImplicitReceiver
# 实际情况 发送隐式广播

测试结果分析

1、小结
测试Receiverintent-filter显式广播结果隐式广播结果原因
1收不到收不到未注册 Receiver
2收到收不到隐式广播在 Android 8.0+ 被限制
3有,匹配的 action收到收不到隐式广播在 Android 8.0+ 被限制
4有,不匹配的 action收到收不到隐式广播在 Android 8.0+ 被限制
  1. 静态注册的 Receiver 使用显式广播

  2. 可以不加 intent-filter(加不加都可以收到)

  3. Receiver 内可以不检查 action,直接接收广播

  4. 如果要检查 action(区分多个 action),显式广播的 Intent 中需要包含 action

2、实践
publicclassExplicitAndImplicitReceiverextendsBroadcastReceiver{publicstaticfinalStringTAG=ExplicitAndImplicitReceiver.class.getSimpleName();@OverridepublicvoidonReceive(Contextcontext,Intentintent){Log.i(TAG,"onReceive start");...Log.i(TAG,"onReceive finish");}}
<receiverandroid:name=".mybroadcast.ExplicitAndImplicitReceiver"android:exported="false"/>
Log.i(TAG,"发送显式广播");Intentintent=newIntent(this,ExplicitAndImplicitReceiver.class);sendBroadcast(intent);

显式广播与隐式广播

-显式广播隐式广播
目标指定明确指定接收者类名不指定接收者,通过 IntentFilter 匹配
接收范围只能被指定的接收者接收可以被多个接收者接收
安全系数较高,只能被指定接收者接收较低,可能被其他应用接收
应用场景应用内组件通信系统广播、跨应用通信

Android 8.0+ 对隐式广播的限制

  1. 从 Android 8.0(API 26)开始,静态注册的广播接收器无法接收大多数隐式广播

  2. 除非是豁免的广播,例如,系统广播


动态注册测试

1、Receiver
publicclassExplicitAndImplicitReceiverextendsBroadcastReceiver{publicstaticfinalStringTAG=ExplicitAndImplicitReceiver.class.getSimpleName();publicstaticfinalStringACTION="broadcast.ExplicitAndImplicitReceiver";@OverridepublicvoidonReceive(Contextcontext,Intentintent){Log.i(TAG,"onReceive start");if(intent==null){Log.i(TAG,"intent is null");return;}Stringaction=intent.getAction();if(action==null){Log.i(TAG,"action is null");return;}if(!action.equals(ACTION)){Log.i(TAG,"action is not "+ACTION);return;}Log.i(TAG,"onReceive finish");}}
2、Activity
  • activity_explicit_and_implicit_receiver_test.xml
<?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:id="@+id/main"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".ExplicitAndImplicitReceiverTestActivity"><Buttonandroid:id="@+id/btn_send_explicit_broadcast"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="发送显式广播"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"/><Buttonandroid:id="@+id/btn_send_implicit_broadcast"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="发送隐式广播"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@+id/btn_send_explicit_broadcast"/></androidx.constraintlayout.widget.ConstraintLayout>
  • ExplicitAndImplicitReceiverTestActivity.java
publicclassExplicitAndImplicitReceiverTestActivityextendsAppCompatActivity{publicstaticfinalStringTAG=ExplicitAndImplicitReceiverTestActivity.class.getSimpleName();privateExplicitAndImplicitReceiverexplicitAndImplicitReceiver;privateButtonbtnSendExplicitBroadcast;privateButtonbtnSendImplicitBroadcast;@OverrideprotectedvoidonStart(){super.onStart();explicitAndImplicitReceiver=newExplicitAndImplicitReceiver();IntentFilterintentFilter=newIntentFilter(ExplicitAndImplicitReceiver.ACTION);registerReceiver(explicitAndImplicitReceiver,intentFilter);}@OverrideprotectedvoidonDestroy(){super.onDestroy();if(explicitAndImplicitReceiver!=null)unregisterReceiver(explicitAndImplicitReceiver);}@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);EdgeToEdge.enable(this);setContentView(R.layout.activity_explicit_and_implicit_receiver_test);ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main),(v,insets)->{InsetssystemBars=insets.getInsets(WindowInsetsCompat.Type.systemBars());v.setPadding(systemBars.left,systemBars.top,systemBars.right,systemBars.bottom);returninsets;});btnSendExplicitBroadcast=findViewById(R.id.btn_send_explicit_broadcast);btnSendImplicitBroadcast=findViewById(R.id.btn_send_implicit_broadcast);btnSendExplicitBroadcast.setOnClickListener(v->{Log.i(TAG,"发送显式广播");Intentintent=newIntent(this,ExplicitAndImplicitReceiver.class);sendBroadcast(intent);});btnSendImplicitBroadcast.setOnClickListener(v->{Log.i(TAG,"发送隐式广播");Intentintent=newIntent(ExplicitAndImplicitReceiver.ACTION);sendBroadcast(intent);});}}
3、Test
(1)不指定 IntentFilter
IntentFilterintentFilter=newIntentFilter();
  1. 发送显式广播,输出结果
发送显式广播
  1. 发送隐式广播,输出结果
发送隐式广播
(2)指定 IntentFilter
IntentFilterintentFilter=newIntentFilter(ExplicitAndImplicitReceiver.ACTION);
  1. 发送显式广播,输出结果
发送显式广播
  1. 发送隐式广播,输出结果
发送隐式广播 onReceive start onReceive finish
小结
  1. 动态注册的 Receiver 使用隐式广播

  2. 指定 IntentFilter

  3. Receiver 内可以不检查 action,直接接收广播(一个 action 的情况)

http://www.jsqmd.com/news/715711/

相关文章:

  • OpenProject开源项目管理平台:基于Ruby on Rails的企业级协同解决方案
  • 专业的山西做GEO搜索优化公司
  • 如何用FigmaCN消除英文界面障碍:设计师的中文设计工作流解决方案
  • 从SOD二极管到SOT晶体管:手把手教你识别PCB上那些迷你SMD封装
  • 新卖家选品方向预警,用好卖家精灵AI工具还有卖家精灵优惠折扣码
  • 除了Copilot,试试VSCode插件GPT Runner:如何用它做项目文档的智能问答助手?
  • 专业干货!低查重的AI教材写作攻略,多款AI工具助力教材编写
  • Rockchip RK3538与RK3572芯片架构与应用解析
  • Lucene底层原理:倒排索引实现原理与代码实战,彻底吃透搜索引擎核心
  • 如何在3天内用Open Images数据集构建你的第一个计算机视觉模型
  • Wan2.2-TI2V-5B终极指南:如何在消费级GPU上实现720P高清AI视频生成
  • 5分钟彻底解决Mac NTFS读写难题:Free-NTFS-for-Mac完整指南
  • 将军思维:在亚马逊,为何“关注对手”比“优化自己”重要一百倍
  • C语言结构体对齐的坑我帮你踩完了:从#pragma pack到__attribute__的避坑指南
  • Pake:革命性的轻量级网页转桌面应用现代化解决方案
  • 收藏!2026 年 AI 薪资炸场:平均月薪 6 万 +,岗位暴涨 12 倍,小白 / 程序员学大模型正当时!
  • 无线串口对传模块:4G全网通适配,远程串口无缝对接
  • 从产品经理视角看:为什么内容运营增长平台一定要用 Redis?
  • AI专著写作神器揭秘:一键生成20万字专著,真实文献引用+低查重!
  • IO管道
  • python学习笔记(day3):文件操作与CSV文件处理
  • 如何高效下载全网资源:Res-Downloader 智能嗅探工具完全指南
  • 大模型多智能体模式详解:新手程序员必备,附收藏指南!
  • 深入S32K3芯片内部:图解FCCU状态机与安全机制(从CONFIG到FAULT的完整流程)
  • STM32 HAL库驱动DRV8301 SPI通信全攻略:从硬件连接到寄存器读写(附避坑清单)
  • AI写专著必备攻略:10种AI工具大揭秘,高效完成20万字专著创作!
  • 通达信缠论插件终极指南:3步实现自动化技术分析,告别手动画线困扰
  • CMake死活找不到OpenCV?别急着重装,先试试这几招(附Windows/Linux/Mac通用解法)
  • 别再手动翻文档了!用CrewAI的这5个搜索工具,5分钟搞定PDF、CSV、网页信息提取
  • 3步掌握Jasminum:Zotero中文文献管理效率提升300%的终极方案