Android 系统中的广播(BroadCast) 是组件与组件进行的一种可跨线程的通信方式。类似于 广播者-订阅者(publish-subscribe) 的实现,当系统或者某个应用的状态发生改变时,发出一个消息来通知其它应用来处理或适应这种改变。发出的这个消息就是 BroadCast. 例如,当系统的电量发生变化时,系统就会发出一个广播,系统的网络状态发生变化时会发出一个 广播。应用可以对自己感兴趣的广播进行接收并处理。

Android 中 广播的分类

  Android 中的广播可以分为两种:标准广播和有序广播

  • 标准广播(Normal BroadCast

  是一种完全以异步方式实现的广播。当广播消息发出后,所有的接收者几乎会在同一时间接收到这个广播,没有任何的先后顺序

  • 有序广播(Ordered BroadCast)

  这种广播以同步的方式来实现。当广播消息发出后,优先级高的接受者总是先于优先级低的接受者收到广播,这种情况下必须上一级的接受者的处理工作完成后才能继续往下传递。甚至优先级高的接受者可以对广播进行截断,被截断后的广播将不再往下传播了。其它的接受者将无法接受到该广播。


  在注册 BroadCastReceiver 时,可以在 Intent-Filter 节点的 android:priority 属性来设置该 Receiver 的优先级(介于 -1000~1000 的整数)


系统广播

  当各种系统事件发生的时候,系统会自动的发出一个广播.广播的信息被包裹在一个 Intent 对象中,Intent 对象的标识字符串(Identity string)会指明所发生的事件,例如,android.intent.action.BOOT_COMPLETED,表明系统启动完成,在 Android SDK目录下的 BROADCAST_ACTIONS.txt 文件中,你可以看到所有的系统 Broadcast-Action。

接受系统广播

  下面的例子,当系统的网络状态发生变化时,在 LogCat 中输出当前的网络状态

  首先,我们需要定义一个广播接收器类(Broadcast Receiver),对接受的广播进行处理

	public class NetWorkStatusChangeReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager manager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = manager.getActiveNetworkInfo(); if(info !=null && info.isAvailable()){
Log.i(TAG,"当前通过 " + info.getTypeName() + " 网络访问");
}else{
Log.i(TAG,"网络连接已断开");
} }
}

  在 AndroidManifest.xml 进行配置,包括两个部分,一部分是获取访问网络状态的权限,一部分是 BrocastReceiver 的注册

  获取权限

	<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

  BrocastReceiver 的注册

	 <receiver android:name=".NetWorkStatusChangeReceiver"
android:enabled="true"
android:exported="true"
>
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>

  在模拟器设置中打开关闭移动网络时,便可以在 LogCat 中看到输出的信息。


  这个例子中我们使用的注册 BrocastReceiver 的方式称为 静态注册(Manifest-declared receivers),既写在 AndroidManifest.xml 文件中。使用此种注册方式注册的 BroadcastReceiver, Android 系统会通过系统包管理器 (System Package Manager) 在应用安装时注册,注册的 Receiver 会成为除了点击应用图标启动应用外的一个独立的应用启动入口。当有广播发出时,如果应用没有在运行,系统可以启动该应用,然后将广播传递给它。

  当收到一条广播时,系统总是会实例化一个新的 BroadCastReceiver 组件去处理该广播。需要注意的是这个 BroadCastReceiver 组件仅在其 onReceiver 内是有效的,如果代码从该方法返回,那么系统就会认为该组件不再处于激活状态了。


BoradCastReceiver 的动态注册

  有静态注册,肯定就有 动态注册 (Context-registered receivers). 动态注册指的是在应用程序运行期间对 BroadCastReceiver 进行注册。

  这里我们使用 动态注册的方法对上面的例子进行重写。

	NetWorkStatusChangeReceiver receiver = new NetWorkStatusChangeReceiver();
IntenFilter filter = new IntentFilter();
filter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
registerReceiver(receiver,filter);

  做完这些就算是完成了 BroadCastReceiver 动态注册的过程.(不要忘记权限的配置)

  通过这种方式注册的 BroadCastReceiver 的生存期长短与其注册时的上下文(Context)有关。如果在一个 Activity 中注册,那么只要这个 Activity 没有被销毁,在其中所注册的 BroadCastReceiver 便是有效的。如果通过 APPContext 进行注册,那么其在整个应用的运行期间都是有效的。


注意: 动态方式注册的 BroadCastReceiver 在不再需要使用或者其上下文无效的时候手动解除注册(UnResiger).例如,如果注册的上下文是一个 Activity,如果在 onCreate(Bundle) 中进行注册,则必须在 onDestory 中解除注册。防止 BroadCastReceiver 脱离上下文而存在。如果在 onResume 中进行注册,则必须在 onPaused 中解除注册。以避免 BroadCastReceiver 被重复注册。


发送广播

  发送一个自定义广播之前需要先定义一个 BroadCastReceiver 来接受该广播,否则发出的广播没有人接受那是没有意义的。下面的例子展示如何发送一个广播

	Intent intent = new Intent();
intent.setAction("packageName.ActionIdentity");
intent.putExtra("data","send some message to you");
sendBroadCast(intent);

  上面的例子,首先实例化一个 Intent 对象,然后设置它的 Action 信息(应用包名称 + BroadCast 事件的唯一标识,方便 BroadCastReceiver注册时 Intent-Filter的筛选 ),如果要发送一个 有序广播 ,可以调用 sendOrderedBroadCast(Intent,String),除此之外,与发送 标准广播 相同。

  不论是发送标准广播还是有序广播,其 send***BroadCast 方法都可以接受一个 String类型的

名称为 permission 的参数,用于指定目标广播接受者所必须具有的权限。既只有被授予了该权限的应用内注册的 BroadCastReceiver 才能给收到该广播(既在应用的 AndroidManifest.xml 文件中请求了该权限)。

	sendBroadCast(intent,Manifest.permission.ACCESS_NETWORK_STATE);

  上面的例子,只有具有 访问网络状态权限的应用内注册的 BroadCastReceiver 才能够接受到该广播

  同样,在注册 BroadCastReceiver 时同样可以为其声明一个权限属性,同样只有具有指定权限的应用发出的广播才会被该 Receiver 接受

	<receiver android:name=".MyBroadcastReceiver"
android:permission="android.permission.SEND_SMS">
<intent-filter>
<action android:name="android.intent.action.AIRPLANE_MODE"/>
</intent-filter>
</receiver>

  Receiver 还可以设置一个 android:export 属性,当设为 FALSE 时,便不再接受所在应用之外BroadCast

本地广播(LocalBroadCast)

  上面所说的广播都是全局广播,既广播发出后设备上的任何一个应用都能够接受,本地广播是相对全局广播来说的,当发出一个本地广播时只有与广播发出者所在的应用才能够接受到。

  发送一个本地广播,需要 Android support 包的支持

	Intent intent = new Intent();
intent.setAction("packageName.ActionIdentity");
intent.putExtra("data","send some message to you");
LocalBroadcastManager.sendBroadcast(intent);

  到这里,关于 BroadReceiver 的基础知识就介绍完了。

android 基础04-BroadCastReceiver的更多相关文章

  1. Android 基础知识 -- BroadcastReceiver

    BroadcastReceiver 广播,是一种事件传递机制,可以跨应用进行事件传递(系统级). 在使用广播的时候,不宜添加过多的逻辑或者耗时(广播内不允许开辟线程)操作,超过10秒,导致ANR 1 ...

  2. Android基础新手教程——4.3.1 BroadcastReceiver牛刀小试

    Android基础新手教程--4.3.1 BroadcastReceiver牛刀小试 标签(空格分隔): Android基础新手教程 本节引言 本节我们将来学习Android四大组件中的第三个:Bro ...

  3. Android基础新手教程——4.3.2 BroadcastReceiver庖丁解牛

    Android基础新手教程--4.3.2 BroadcastReceiver庖丁解牛 标签(空格分隔): Android基础新手教程 本节引言: 上节我们对BroadcastReceiver已经有了一 ...

  4. Android基础总结(8)——服务

    服务(Service)是Android中实现程序后台运行的解决方案,它非常适合用于去执行哪些不需要和用户交互而且还要长期运行的任务.服务的运行不依赖任何用户界面,即使当程序被切换到后台,或者用户打开了 ...

  5. Android基础知识巩固:关于PendingIntent和广播

    平时使用广播的场合比较多,但细节的东西,看过了也没有总结,以至于某些场合有小问题,还是要把原理和属性搞清楚才能运用自如. 其实也是自己比较懒,先看别人的blog,有个概念再去官网看英文的能好理解一些. ...

  6. Android基础总结+SQlite数据库【申明:来源于网络】

    Android基础总结+SQlite数据库[申明:来源于网络] 基础总结篇之一:Activity生命周期:http://blog.csdn.net/liuhe688/article/details/6 ...

  7. Android基础测试题(四)

    看了前两道题大家有没有发现,测试题少了(一),大家猜猜测试题(一)是什么? Android基础测试题(四): 需求: 建一个方法,格式化输出2016-11-14 10:15:26格式的当前时间,然后截 ...

  8. Android基础测试题(二)

    今天给大家带来的是Android基础测试题(二) 题目要求: 定义一个5位长度的整型数组并初始化,然后构建方法根据用户传入的数字判断是否存在数组中,如果存在,返回所在位置,如果不存在,返回-1 首先第 ...

  9. javaSE基础04

    javaSE基础04 一.三木运算符 <表达式1> ? <表达式2> : <表达式3> "?"运算符的含义是: 先求表达式1的值, 如果为真, ...

  10. javascript基础04

    javascript基础04 1.循环语句 1.While 语句: while (exp) { //statements; } var i = 1; while(i < 3){ alert(i) ...

随机推荐

  1. 基于zepto的移动端日期和时间选择控件

    前段时间给大家分享过一个基于jQuery Mobile的移动端日期时间拾取器,大家反应其由于加载过大的插件导致影响调用速度.那么今天我把从网络上搜集到的两个适合移动端应用的日期和时间选择插件分享给大家 ...

  2. 在vim中使用zencoding/Emmet

    zencoding在vim上的插件已经改名为Emmet.vim 1. 安装,推荐使用vundle插件管理器安装,在~/.vimrc中,添加:Bundle 'Emmet.vim',输入命令vim +Bu ...

  3. Head First设计模式之原型模式

    一.定义 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 原型模式是一种比较简单的模式,也非常容易理解,实现一个接口,重写一个方法即完成了原型模式.在实际应用中,原型模式很少单独出现 ...

  4. sql server 错误号大全

    0 操作成功完成. 1 功能错误. 2 系统找不到指定的文件. 3 系统找不到指定的路径. 4 系统无法打开文件. 5 拒绝访问. 6 句柄无效. 7 存储控制块被损坏. 8 存储空间不足,无法处理此 ...

  5. CSS 鼠标样式大全

    cursor是CSS中用于定义鼠标在元素标签上的显示样式,如常用的手型鼠标样式 cursor: pointer; 也可以通过url网址指定扩展名一般为.cur的鼠标图片文件. 名称 属性代码 描述 默 ...

  6. 关于“System.Data.OleDb.OleDbException,外部数据库驱动程序 (1) 中的意外错误。”的解决方案

    网站之前运行一直很正常,但有一次用户在导入格式为xls的excel文件,发生了错误,跟踪错误后抛出如下的异常: 错误提示: 未处理System.Data.OleDb.OleDbException HR ...

  7. Jerry的ABAP, Java和JavaScript乱炖

    写这个系列的初衷是SAP Chengdu office有越来越多的应届毕业生加入,这些新同事通过在大学的专业学习,具备了Java和JavaScript背景,但是进入SAP之后大家觉得ABAP没有Jav ...

  8. 实现数组元素互换位置(乘机理解java参数传递)

    Java中函数参数是按值传递的,在实现数组元素互换位置之前,我想先说一下Java函数参数传递过程.一般情况下我们会把参数分为基本数据类型和引用数据类型,然后分别来讲参数传递,因为他们的外在表现似乎是不 ...

  9. JAVA实现跳一跳辅助程序之虎啸龙吟

    前序: 今天有幸,看到2位博主的文章,在此表示感谢.自己也动手实现了一下. 实现原理 请参考博主 https://www.cnblogs.com/dongkuo/p/8285162.html 另感谢博 ...

  10. ECharts模拟迁徙案例

    ECharts模拟迁徙案例 独立页面:http://211.140.7.173:8081/t/wuhairui/ditu/a.html