android 基础04-BroadCastReceiver
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的更多相关文章
- Android 基础知识 -- BroadcastReceiver
BroadcastReceiver 广播,是一种事件传递机制,可以跨应用进行事件传递(系统级). 在使用广播的时候,不宜添加过多的逻辑或者耗时(广播内不允许开辟线程)操作,超过10秒,导致ANR 1 ...
- Android基础新手教程——4.3.1 BroadcastReceiver牛刀小试
Android基础新手教程--4.3.1 BroadcastReceiver牛刀小试 标签(空格分隔): Android基础新手教程 本节引言 本节我们将来学习Android四大组件中的第三个:Bro ...
- Android基础新手教程——4.3.2 BroadcastReceiver庖丁解牛
Android基础新手教程--4.3.2 BroadcastReceiver庖丁解牛 标签(空格分隔): Android基础新手教程 本节引言: 上节我们对BroadcastReceiver已经有了一 ...
- Android基础总结(8)——服务
服务(Service)是Android中实现程序后台运行的解决方案,它非常适合用于去执行哪些不需要和用户交互而且还要长期运行的任务.服务的运行不依赖任何用户界面,即使当程序被切换到后台,或者用户打开了 ...
- Android基础知识巩固:关于PendingIntent和广播
平时使用广播的场合比较多,但细节的东西,看过了也没有总结,以至于某些场合有小问题,还是要把原理和属性搞清楚才能运用自如. 其实也是自己比较懒,先看别人的blog,有个概念再去官网看英文的能好理解一些. ...
- Android基础总结+SQlite数据库【申明:来源于网络】
Android基础总结+SQlite数据库[申明:来源于网络] 基础总结篇之一:Activity生命周期:http://blog.csdn.net/liuhe688/article/details/6 ...
- Android基础测试题(四)
看了前两道题大家有没有发现,测试题少了(一),大家猜猜测试题(一)是什么? Android基础测试题(四): 需求: 建一个方法,格式化输出2016-11-14 10:15:26格式的当前时间,然后截 ...
- Android基础测试题(二)
今天给大家带来的是Android基础测试题(二) 题目要求: 定义一个5位长度的整型数组并初始化,然后构建方法根据用户传入的数字判断是否存在数组中,如果存在,返回所在位置,如果不存在,返回-1 首先第 ...
- javaSE基础04
javaSE基础04 一.三木运算符 <表达式1> ? <表达式2> : <表达式3> "?"运算符的含义是: 先求表达式1的值, 如果为真, ...
- javascript基础04
javascript基础04 1.循环语句 1.While 语句: while (exp) { //statements; } var i = 1; while(i < 3){ alert(i) ...
随机推荐
- MicroPython教程之TPYBoard v102 CAN总线通信
0x00前言 CAN是控制器局域网络(ControllerAreaNetwork,CAN)的简称,是ISO国际标准化的串行通信协议.CAN总线结构简单,只需2根线与外部相连,并且内部集成了错误探测和管 ...
- Hyperledger Fabric 本地运行的简单示例
环境: Ubuntu 16.04 go 1.7.4 版本: Fabric v1.0.0-alpha 本文主要目的就是让大家体验以下Fabric网络环境搭建的具体过程,不基于集成化脚本手动搭建. 一.编 ...
- java基础概述
写代码: 1,明确需求. 2,分析思路. 3,确定步骤. 4,代码实现. Java的三种技术架构: JAVAEE:Java Platform Enterprise Edition,开发企业环境下的应用 ...
- 【vue系列之三】从一个vue-pdf-shower,说说vue组件和npm包
前言 从去年年初开始,自己便下决心要写一个vue系列的博客,但时至今日,才写系列的第三篇博客,想来甚是惭愧. 但是慢归慢,每一篇都要保证质量,以及要写出自己的心路历程,防止自己工作中填的坑再让读者走一 ...
- DIV里面的图片水平与垂直居中的方法
<div class=“box”> <img /> </div> 1.水平居中: 1)box设置 text-align:center ; text-alig ...
- Java集合系列[2]----LinkedList源码分析
上篇我们分析了ArrayList的底层实现,知道了ArrayList底层是基于数组实现的,因此具有查找修改快而插入删除慢的特点.本篇介绍的LinkedList是List接口的另一种实现,它的底层是基于 ...
- 【CentOS】php编译安装gd库
一.准备工作 使用之前服务器按源码最小化安装完nginx.php-fpm,没有安装gd库,下面介绍下gd库的安装. gd库是一个开源的图像处理库,它通过提供一系列用来处理图片的API,使其可以用来创建 ...
- 有关java里,nextLine()无法输入的问题
在课后习题中用到了以下代码 public static void main(String[] args) { System.out.print("输入学生人数:"); int st ...
- Python 之 基础知识(一)
首先,对于初学者在一个项目中设置多个程序可以执行,是非常方便的,可以方便对不同知识点的练习和测试 对于商业项目而言,通常在一个项目中,只有一个可以执行的Python程序 一.注释 为了提高可读性,注释 ...
- 2039: [2009国家集训队]employ人员雇佣
任意门 Description 作为一个富有经营头脑的富翁,小L决定从本国最优秀的经理中雇佣一些来经营自己的公司.这些经理相互之间合作有一个贡献指数,(我们用Ei,j表示i经理对j经理的了解程度),即 ...