Android组件- 广播的静态动态有序无序与优先级

BoradCast Receiver 阅读详情

设计模式中有一种比较常用的模式——观察者模式:观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时接收某一个主题对象的消息。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。Android中的广播接收器,就是观察者模式经典的案例,基于对观察者模式的理解,我们也应当对BroadcastReceiver的优缺点有个基本认识。

优点:广播发送者与接收者的耦合度很低,可以非常便利的解耦重构接收者的业务逻辑,解除耦合关系。

缺点:如果广播发送者有很多的接收者的话,要通知到所有的接收者需要一定的时间。


对BroadcastReceiver的设计思想有了一定了解之后,我们再来看Android BroadcastReceiver的一些关键知识点:

一. 普通(无序)广播和有序广播

1. 普通(无序)广播: 所有接收器都是异步处理的,所有注册的广播接收器在同一时间(理论上~)收到广播消息,收到的消息都是一致的,互相不能改变广播消息,也不能终止广播的发送。

2. 有序广播:做为对立面,可以想象普通广播不能做的,在这里可以做。

a). 广播消息是按照注册接收器时声明的优先级,按顺序发给各个接收器的,优先级最大可以声明为int型的最大值,也就是2147483647(为了最高优先级,拼了)。

b). 优先收到广播的接收者,可以改变消息的内容,将自己的处理结果发给下一个接收者。当然,也可以直接中断这个广播,后面的接收者就无法接收了。

有人就有江湖,有优先级就有竞争,一个典型的案例就是市场上各个通讯录产品,比如QQ,91通讯录,为什么他们可以拦截系统短信,把新的短信放到自己的库里面呢?其实原理很简单,就是有序广播。Android系统的短信是通过有序广播发送的,系统原生的短信app也是通过注册BroadcastReceiver来处理短信,因此我们只要在注册一个短信接收器,把优先级调到最最高的2147483647(QQ,91们估计就是这么干的),就能在系统原生的短信app之前,接收到短信广播,接下来爱干嘛干嘛了。

好奇的同学估计会问,都是2147483647,顺序是怎样的呢?答,谁先注册,谁先调用。

好奇的同学估计还会问,都是2147483647,有没可能都是我注册的先调用?答,有可能,通过动态注册!因为相同优先级的广播接收器,动态注册的会排在静态注册的前面。

接下来,就让我们来看第二个关键知识点。


二. 静态广播和动态广播

1. 先说明下,这里把静态注册的广播简称为静态广播,动态注册的广播简称为动态广播。

静态注册是通过AndroidManifest的标签<receiver>来实现的:

<receiver android:name="com.yourapp.demoReceiver">
            <intent-filter>
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
            </intent-filter>
</receiver>

动态广播则是通过代码来注册的:

public class BrocastReceiverDemo extends Activity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		IntentFilter filter = new IntentFilter();
		filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
		
		this.registerReceiver(connectChangedReceiver, filter);
	}
	
	@Override
	protected void onDestroy() {
		super.onDestroy();
		if (connectChangedReceiver != null)
			this.unregisterReceiver(connectChangedReceiver);
	}
	
	BroadcastReceiver connectChangedReceiver = new BroadcastReceiver() {
		@Override
		public void onReceive(Context context, Intent intent) {
			//doSomething();
		}
	};
}
2. 动态广播能做的,静态广播也能做,但是反过来就不成立了,接下来就一起看看静态广播有哪些特性。

a). 静态广播不依赖于应用的进程,换句话说就是即使我们的应用没开启,也可以接收广播。市场上一大票开机自启动的应用,就是注册了手机的开机广播来实现的。

b). 静态广播可以增加android:exported="false"的设置,限制只能接收本应用的广播消息。注意,加了android:exported="false",系统的广播也接收不到了。

c). 关于a中说明的特性,在4.X系统中有一个bug,如果我们的app在安装过后从未启动,静态广播不会生效。虽然网上贴有一些特殊的方法来解决,但还是有ROM的适配问题(有兴趣的同学可以自行百度,关键字intent.setFlags(32))。


三. 广播接收器的其他要点

1. BroadcastReceiver.onReceive默认是在主线程(UI线程)执行的,这也是老生常谈的“千万不能在广播接收器做耗时操作,会ANR!”的真正原因。

2. 广播发送者可以指定接收广播的应用,只要将sendBroadcast(intent)的intent加上具体的包名就行了,intent.setPackage("yourpackagename")。

3. 广播发送者和接收者都可以声明权限,这样只有在AndroidManifest声明对应权限,才能接收到相应的广播消息。



接收广播的最高优先级 @SuppressLint("NewApi") public class MainActivity extends Activity { SmsReceiver myReceiver; Button btn; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn = (Button) findViewById(R.id.btn); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { test(); } }); } public void test(){ Cursor cursor = null; String defaultSmsApp = Telephony.Sms.getDefaultSmsPackage(this); Intent intent = new Intent(Sms.Intents.ACTION_CHANGE_DEFAULT); intent.putExtra(Sms.Intents.EXTRA_PACKAGE_NAME, this.getPackageName()); startActivity(intent); try { cursor = getContentResolver().query(Uri.parse("content://sms/inbox"), new String[] { "_id", "address", "read" }, "read = ? ", new String[] {"0" }, "date desc"); if (cursor != null) { ContentValues values = new ContentValues(); values.put("read", "1"); for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) { Log.v("cky", "" + cursor.getInt(cursor.getColumnIndex("_id")) + " , " + cursor.getString(cursor.getColumnIndex("address"))); int res = getContentResolver().update(Uri.parse("content://sms/inbox"), values, "_id=?", new String[] { "" + cursor.getInt(cursor.getColumnIndex("_id")) }); Log.i("cky","geng xin = "+res); } } intent = new Intent(Sms.Intents.ACTION_CHANGE_DEFAULT); intent.putExtra(Sms.Intents.EXTRA_PACKAGE_NAME, defaultSmsApp); startActivity(intent); } catch (Exception e) { e.printStackTrace(); } finally { if (cursor != null) { cursor.close(); cursor = null; } } } } 立即下载

相关推荐

Vc出现不能连接到一个或多个 vCenter server 系统:http://vcenter-vx.utibet.edu.cn:443/sdk

问题描述: 解决办法: esxi6.7的bug 第一种通过升级系统来解决问题 第二种是通过删除数据来解决 第一步:进入到esxi的shell 第二步查看其中的服务开启状态 第二步 df -h 第三步 /opt/vmware/vpostgres/current/bin/psql -d VCDB -U postgres 第四步 SELECT nspname || '.' || relname AS "relation", pg_size_pretty(pg_total_relation_size(C.oi

m0_49328536的博客 9900

android广播接收器的无序广播和有序广播

android广播接收器的无序广播和有序广播

ShiXinXin_Harbour的博客 2980

用易经智慧看懂人工智能:64卦中的科技密码--当古老智慧遇见未来科技

在人工智能狂飙突进的今天,我们总在追问:这些代码构建的智能究竟会带人类走向何方?或许答案早已藏在《周易》的六十四卦中——这本中华文明的“源代码”,正用一种跨越时空的语言,悄悄解释着最前沿的科技秘密。

weixin_38410320的博客 2084

android的广播broadcast和receiver && 广播接收器优先级的深入分析

(1)基础概念        广播发送者:通常广播发送方就是调用Context.sendBroadcast()的程序,而广播接收者就是继承BroadcastReceiver的程序。广播发送分两种: A,无序广播:发送方发出后,几乎同时到达多个广播接收者处,并且无法终止广播继续传播,使用Context.sendBroadcast(intent); B,有序广播:广播接收者需要提前设置优先级,优

zhandoushi的专栏 3万+

matebookego win11 arm 系统安装安卓子系统

一般的x86电脑如果安装android子系统,运行安卓子系统,由于要将android arm代码转译为x86代码,所以效率不一定高,但是如果电脑是arm架构的,通过安卓子系统运行android的程序执行效率就会 高不少,本文参考,都是在win11 home版本下的。两者跑分在cpu上差不太多了,大约是枭龙855的水平了,这个水平的子系统就有一定的实用性了,玩个一般游戏,刷个抖音都很流畅的。启动子系统后,点击左上角的设置,启用 “开发人员模式”。然后就可以再通运运行华为应用商店来进行安装其它应用了。

babytiger的专栏 1万+

从零解析特斯拉线圈:谐振变压器的核心原理与DIY实践

本文深入解析特斯拉线圈的工作原理与DIY实践,从LC振荡电路到电磁耦合,详细介绍了谐振变压器的核心原理。通过材料清单、绕制技巧和安全指南,帮助爱好者从零开始打造迷你闪电发生器,体验高压电子实验的独特魅力。

weixin_33670786的博客 493

Android广播详解

在Android系统粘性广播一般用来确保重要的状态改变后的信息被持久保存,并且能随时广播给新的广播接收器,比如电源的改变,因为耗电需要一个过程,前一个过程必须提前得到,否则可能遇到下次刚好接收到的广播后系统自动关机了,随之而来的是kill行为,所以对某些未处理完的任务来说,后果很严重。如果想要接受这些广播,就需要使用广播接收器。顾名思义,一种有序的,同步的广播,它是按照次序来传递,先被优先级高的接收器接收到,响应完成后再传递给接收器B然后C,同时可以进行截断,比如在A处截断,后续B和C就无法接收到广播。

weixin_40323532的博客 4579

攻防世界GFSJ1184_welcome_CAT_CTF

由于它是 PIE 可执行文件,程序加载地址会随机化,这导致你在 GDB 调试时需要处理地址偏移(如 0x246d 变成 0x55555540246d)。:client 程序通过网络连接(get_nc() 和 get_flag(nc))与 server 通信,server 监听在端口 8888。:client 依赖外部共享库(如 libstdc++.so),因此运行时需要这些库存在系统中。程序就是wasd移动,走到不同标记(* $ @ )下方,输入j回车,会有不同反应。两个文件client和server。

拥抱AI的老粽子 1262

广播——BroadcastReceiver的有序广播和优先级

转自http://www.cnblogs.com/codingblock/p/4856559.html 一、两种Broadcast:   · 普通广播(Normal Broadcast):用sendBroadcast()方法发送。   普通广播是完全异步的,逻辑上可以在同一时刻被所有匹配的接受者接收到,消息传递效率高,缺点是接受者不能将处理结果传递给下一个接收者,也无法终止广

chuntiandejiaobu10的专栏 6681

PyTorch实战:用FGSM攻击MNIST分类器(附可视化对比)

本文通过PyTorch实战演示了如何使用FGSM对抗攻击方法攻击MNIST手写数字分类器。文章详细解析了FGSM攻击原理,提供了从环境搭建、模型准备到攻击实施、可视化对比的完整代码实战流程,并探讨了对抗样本的生成与模型鲁棒性评估。

3a9bq4r8t2y的博客 216

【数据集】中国陆地生态系统通量观测网 ChinaFLUX

【数据集】中国陆地生态系统通量观测网 ChinaFLUX

WW、forever的博客 189

Android四大组件之BroadCastReceive

hello,大家好 ,我是小杰,前几篇博文中我给大家介绍了四大组件的其中两种,今天给大家介绍一下第三个组件,BroadCastReceive,也就是广播接受者。广播是通过Intent发送action,然后注册一个接受者来接收这个action从而进行一些操作。  广播的发送方式 无序广播 有序广播 无序广播是所有的接收者都可以接收到这个action从而进行操作,而有序广播是根据优先级不同来进行...

ZCJ-阿杰的博客 297

Linux内核4.14版本——drm框架分析(1)——drm简介

本文介绍了DRM架构的发展历史、驱动框架以及简单示例,旨在帮助读者了解DRM架构的形成、功能流程实现。

phmatthaus的专栏 2556

android截取系统广播,Android四大组件之BroadcastReceiver学习

一、BroadcastReceiver简介1.BroadcastReceiver是Android四大组件之一。一般的都要在清单文件中进行静态注册。但是只有广播接收者可以在java代码中进行动态注册2.BroadcastReceiver是用于接收广播的组件,用于组件与组件之间进行通信,可以跨应用程序传递3.广播的发送适用场合:发送频率低的情况使用,数据量小的时候使用,因为intent不能携带太大的数...

weixin_35846141的博客 479

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

Android四大组件:Broadcast

Android广播机制分为标准广播和有序广播。标准广播完全异步,所有接收器同时接收,效率高但不可截断;有序广播同步执行,按优先级顺序传递,可被前序接收器截断。系统广播可通过动态或静态注册监听,动态注册需在代码中创建接收器并关联IntentFilter,静态注册则在Manifest文件中声明,可实现开机启动等功能。自定义广播接收器需继承BroadcastReceiver并重写onReceive()方法。标准广播的发送和接收示例展示了基本的实现流程,而有序广播允许优先级控制和广播截断。

giaoho的博客 2142

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

探秘安卓广播:揭秘Android广播机制的神奇之处

当系统提供的广播不能满足实际需求时,可以自定义广播,同时需要编写对应的广播接收者。当自定义广播发送消息时,会储存到公共消息区中,而公共消息区中如果存在对应的广播接收者,就会及时的接收这条信息。

缘友一世的博客 1439

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

第八章-Android广播机制

Broadcast Receiver是Andriod四大组件之一(Activity,Service,Broadcast Receiver,Content Providers),主要是用于广播消息和接受消息。例如:系统在运行过程中,会发生很多事件,系统为了让其他应用知道系统发生了这个事件,会发送一个对应该事件的广播,比如:电量改变、收到短信、拨打电话、屏幕解锁、系统开机,应用只要注册一个广播接收者,就可以接收到系统发出的广播。

ZMMMOO的博客 715

Android的Broadcast的注册方式,对应的生命周期是什么,有序和无序那种可以中断广播?

Android的Broadcast的注册方式,对应的生命周期是什么,有序和无序那种可以中断广播?

QYgujingjing的专栏 1091

安卓四大组件之——BroadcastReceiver广播的详细解析

BroadcastReceiver 身为安卓的四大组件之一,其使用率非常普遍,所以我们要熟练掌握其使用方法。 1,广播的注册方式有两种:静态注册和动态注册 1),静态注册:需要在Androidmanifest 中进行声明,主要用于全局APP中监听,只有完全退出APP才能让其停止工作。 2),动态注册:在代码中注册,不需要在Androidmanifest进行声明,其生命周期随着活

www121104115的博客 596

BroadcastReceiver(广播)的讲解与实例

什么是广播: 广播是Android四大组件之一,全称BroadcastReceiver 广播分为接收方和发送方,就算没有接收方,发送方也会发送数据 可以实现跨多个页面间的数据通信通信 可以实现跨进程间的数据通信 静态注册无序广播: 实现效果:实现两个软件之间的数据通信 1.新建自定义类继承BroadcastReceiver,复写onReceive(...

shaochen2015821426的博客 2093

Android开发之Broadcast Receive(广播机制)其实开发如此简单

BroadcastReceiver(广播接收器)用于响应来自其他应用程序或者系统的广播消息。这些消息有时被称为事件或者意图。本质上来讲BroadcastReceiver是一个全局的监听器,隶属于Android四大组件之一。

qq_38999743的博客 557

广播机制-广播接收者BroadcastReceiver

在Android中,广播是一种在组件之间传递消息的机制,例如电池电量低时会发送一条提示如果要接收并过滤广播中的消息,则需要使用Broadcast Receiver(广播接收者)。,通过广播接收者可以监听系统中的广播消息,实现在不同组件之间的通信。

m0_57150356的博客 824

Android --- 广播

一种相互通信,传递信息的机制,组件内、进程间(App之间)

weixin_43244083的博客 797

Android学习之路--四大组件--BroadCastReceiver

四大组件 Activity BroadCastReceiver Service ContentProvider

竹林贤子的专栏 789

Android的广播接收者

介绍   广播接收者是Android的四大组件,与其他组件不同,广播接收者可以动态注册,用于接收到广播后处理,也可起着进程间通信作用,了解到Android用多种通信方式,那为什么还要搞个广播接收者让我们学呢? 广播机制有着牢固的地位,广播接收者和发送者是无需知道对方的存在和位置,使用简单,使得应用程序高内聚低耦合,降低工作量,维护和风险。 生命周期注意事项:   广播的生命周期极其短暂,最好不要做...

Eliza白的博客 558
上一篇: Android组件-Activity生命周期与回调机制
shiftjava
博客等级 码龄19年 1粉丝 3原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值