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. 4、公司经营的业务来源 - CEO之公司管理经验谈

    公司经营的业务来源为公司的运作资金提供了帮助,一般来说,整个公司的领导层为公司的经营做管理,而业务员就为公司的业务提供来源,然后建设部为业务开展做建设. 一.总经理: 公司的总经理主要负责公司运作经营 ...

  2. 在macOS上通过pyenv安装和切换多版本Python

    1. 安装homebrew 官网 http://brew.sh/index_zh-cn.html 打开终端,在终端中粘贴如下脚本 /usr/bin/ruby -e "$(curl -fsSL ...

  3. Linux中创建新用户并赋给指定文件权限

    工作中用到了,写篇日志总结一下. 创建新的用户: 第一种方式: 创建用户: adduser name 创建密码: passwd name(回车后出现修改密码的提示) 该方式创建的用户目录默认在home ...

  4. 6月22日项目CodeReview问题及总结

    后台代码部分 1. 枚举类的使用:当定义的某个字段有多种状态值或表示值时,可以创建一个枚举类将所有状态表示出来,并供其他使用到该字段的方法统一调用.枚举类定义可参考 '/banking-dbbp-pr ...

  5. IDEA第六章----快捷键

    第一节:解决快捷键冲突 idea支持很多快捷键,这样就导致了很多快捷键和其他应用冲突,所以需要把其他应用的快捷键去掉,下面以输入法和QQ为例. QQ我就留下了提取消息和截图,这个是个人习惯问题. 第二 ...

  6. js获取指定时间的前几秒

    最近项目上有一个需求是:根据一张图片的拍摄时间获取到这个时间前二后三的一个五秒钟的视频信息,通过查找相关资料写了一个方法拿来记录分享一下. //指定时间减2秒function reduceTwoS(d ...

  7. python爬虫下载文件

    python爬虫下载文件 下载东西和访问网页差不多,这里以下载我以前做的一个安卓小游戏为例 地址为:http://hjwachhy.site/game/only_v1.1.1.apk 首先下载到内存 ...

  8. JavaScript对于switch语句中的case后键入值的带不带引号

    一.用switch选择星期几 这时case为  例:case="星期一" 二.用switch选择单纯的数字 这时case为  例:case='1' 三.用switch选择一个应用了 ...

  9. ajax 处理请求回来的数据

    比如接口 /test, 请求方式get, 请求过来的数据要处理在container 里,如下代码 $.get("/test", {}, function(result){ $(&q ...

  10. 解决Fiddler出现无线弹框 "creation of the root certificate was not successful”的问题

    打开Fiddler 访问:http://localhost:8888/ 安装证书,如果提示没有证书(8888是你在Tool->Fiddler Option->Connections设置的F ...