10.7 接收广播消息

Android系统的四大组件还有一种BroadcastReceiver,这种组件本质上就是一个全局监听器,用于监听全局的广播消息。由于BroadcastReceiver是一个全局监听器,因此它可以非常方便地实现系统中不同组件之间的通讯。例如,我们希望客户端程序与startService()方法启动的Service之间通讯,就可以借助于BroadcastReceiver来实现。

10.7.1 BroadcastReceiver用于接收程序(包括用户开发的程序和系统内建的程序)所发出的Broadcast Intent,与应用程序启动Activity、Service相同的是,程序启动BroadcastReceiver也只需要两步。

1、创建需要启动的BroadcastReceiver的Intent。

2、调用Content的sendBroadcast()或sendOrderdBroadcast()方法启动指定的BroadcastReceiver。

与Activity、Service具有完整的生命周期不同,BroadcastReceiver本质上只是一个系统级的监听器--------它专门负责监听个程序所发出的Broadcast。

提示:

前面介绍的各种OnXxxListener只是程序级别的监听器,这些监听器运行在指定程序所在进程中,当程序退出时,onXxxListener监听器也就随之关闭了。但BroadcastReceiver属于系统级的监听器,他拥有自己的进程,只要存在与之匹配的Intent被广播出来,BroadcastReceiver就会被激发。

由于BroadcastReceiver本质上属于一个监听器,因此实现BroadcastReceiver的方法也十分简单,只要重写BroadcastReceiver的onReceive(Content content,Intent intent)方法即可。

一旦实现了BroadcastReceiver,接下来就应该指定该BroadcastReceiver能匹配的Intent,此时有两种方式。

1、使用代码进行指定,调用BroadcastReceiver的Content的registerReceiver(BroadcastReceiver receiver,IntentFilter filter)方法指定。例如如下代码

2、在AndroidManifest.xml文件中配置。例如如下代码:

每次系统Broadcast事件发生后,系统就会创建对应的BroadcastReceiver实例,并自动触发它的onReceive()方法,onReceive()方法执行完后,BroadcastReceiver实例就会被销毁。

提示:

与Activity组件不同的是,当系统通过Intent启动指定了Activity组件时,如果系统没有找到合适的Activity组件,则会导致程序异常终止;单系统通过Intent激发BroadcastReceiver时,如果找不到合适的BroadcastReceiver组件,应用不会有任何问题 。

如果BroadcastReceiver的onReceive()方法不能在10秒内执行完成,Android会认为该程序无响应,所以不要在BroadcastReceiver的onReceive()方法里面执行一些耗时操作;否则会弹出ANR(Application No Response)对话框。

如果确实需要根据Broadcast来完成意向比较耗时的操作,则可以考虑通过Intent启动一个Service来完成该操作。不应该考虑使用新线程去完成耗时操作,因为BroadcastReceiver本省的生命周期很短,可能出现的情况是子线程还没有结束,BroadcastReceiver就已经退出了。

如果BroadcastReceiver所在的进程结束了,虽然该进程内还有用户启动的新线程,但由于该进程内不包含任何活动组件,因此系统可能在内存紧张时优先结束该进程。这样就可能导致BroadcastReceiver启动的子线程不能执行完成。

10.7.2  发送广播

在程序中发送广播十分简单,只要调用Content的sendBroadast(Intent intent)方法即可,这条广播将会启动intent参数所对应的BroadcastReceiver。

下面简单的程序示范了如何发送Broadcast、使用BroadcastReceiver接收广播。该程序的Activity界面中包含一个按钮,当用户单击按钮时程序会向外发送一条广播,该程序的代码如下。

上面的程序中创建了一个Intent对象,并使用该Intent对象对外发送一条广播。个hi按行层序所使用的BroadcastReceiver代码如下。

真能够如上面的程序中看到的,当符合该action的广播出现时,该广播的onReceive()方法将会被处罚,从而在该方法中显示广播携带的消息。

上面发送广播的程序中指定发送广播时所用的Intent的Action为org.cxrazyit.action.CRAZY_BROADCAST,这就需要配置上面的BroadcastReceiver应监听Action为该字符串的Intent,在AndroidManifest.xml文件中增加如下配置即可:

可以运行一下试试看

10.7.3 有序广播

Broadcast被分为如下两种。

1、Normal Broadcast(普通广播):Normal Broadcast是完全异步的,可以在同一时刻(逻辑上)被所有的接收者接收到,消息传递的效率比较高。但缺点是接收者不能将处理结果传递给下一个接收者,并却无法终止Broadcast Intent的传播。

2、Ordered Broadcast(有序广播):Ordered Broadcast的接收者将预先声明的优先级依次接收Broadcast。比如A的级别高于B、B的级别高于C,那么Broadcast先传给A,再传给B。最后传给C。优先级别声明在<intent-filter.....>元素的android:priority属性中,数越大级别越高,取值范围-1000-1000,也可以调用IntentFilter对象的setPriority()设置优先级别。Ordered Broadcast接收者可以终止Broadcast Intent的传播。Broadcast Intent的出阿伯一旦终止,后面的接收者就无法接收到Broadcast。另外,Ordered Broadcast的接收者可以将数据传递给下一个结合搜着,比如A得到Broadcast后,可以往它的结果对象中存入数据,当Broadcast传给B,B可以从A的结果对象得到A存入的数据。

Content提供两个方法用于发送广播。

sendBroadcast() :发送Normal Broadcast。

sendOrderedBroadcast():发送Ordered Broadcast

对于Ordered Broadcast而言,系统会根据接收者声明的优先级别按顺序诸葛执行接收者,优先接受到Broadcast的接收者可以终止Broadcast,调用BroadcastReceiver的abortBroadcast()

方法即刻终止Broadcast。如果Broadcast背前面的接收者终止,后面的广播接收者就在也无法获取到Broadcast了。

不仅如此,对于Ordered Broadcast而言,优先接收到Broadcast的接收者可以通过serResultExtras(Bundle)方法将处理结果存入Broadcast中,然后传给下一个接收者,下一个接收者通过代码Bundle bundle = getResultExtras(true)可以获取上一个接收者存入的数据。

提示:

系统接收到短信,发出Broadcast属于Ordered  Broadcast。如果想阻止用户收到短信,可以通过设置优先级,让自定义的BroadcastReceiver现货区到Broadcast,然后总之Broadcast。

接下来介绍一下发送广播的示例,该程序的Activity界面上只有一个普通的按钮,用于发送一条有序广播。该程序代码如下。



上面程序中的粗体字代码指定了Intent的Action属性,再调用endOrderedBroadcast()方法来发送有序广播。对于有序广播而言,他会按优先级依次触发每个BroadcastReceiver的onReceive()方法。

下面的程序定义了第一个BroadcastReceiver。

上面的BroadcastReceiver不仅处理了他所接受的消息,而且向处理结果中存入了Key为first的消息,这个消息将可以被第二个BroadcastReceiver解析出来。

上面的程序中的1号字体代码用于取消广播,如果保持这条代码生效,那么优先级比MyReceiver低的BroadcastReceiver都将不会被处罚。

在AndroidManifest.xml文件中部署该BroadcastReceiver,并制定其优先级为20.配置片段如下:

接下来微程序提供第二个BroadcastReceiver,这个BroadcastReceiver将会解析前一个BroadcastReceiver所存入的Key为first的消息。该BroadcastReceiver的代码如下。


上面程序的代码用于解析前一个BroadcastReceiver存储结果的Key为first的消息,在AndroidManifest.xml文件中配置该BroadcastReceiver,并指定其优先级为0.配置片段消息如下:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,636评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,890评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,680评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,766评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,665评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,045评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,515评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,182评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,334评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,274评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,319评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,002评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,599评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,675评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,917评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,309评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,885评论 2 341

推荐阅读更多精彩内容