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) ...
随机推荐
- [SDOI2009]E&D
题目描述 小E 与小W 进行一项名为“E&D”游戏. 游戏的规则如下: 桌子上有2n 堆石子,编号为1..2n.其中,为了方便起见,我们将第2k-1 堆与第2k 堆 (1 ≤ k ≤ n)视为 ...
- Python新式类继承的C3算法
在Python的新式类中,方法解析顺序并非是广度优先的算法,而是采用C3算法,只是在某些情况下,C3算法的结果恰巧符合广度优先算法的结果. 可以通过代码来验证下: class NewStyleClas ...
- 通过tokenPlease()函数获取accessToken
作者:陈希章 发表于 2018年1月5日 这是一个很小的技巧,而且用几句话就能讲明白.事情是这样的,我最近在回顾之前写过的文章:通过其他第三方工具体验Microsoft Graph 的时候,发现最近的 ...
- Dotnet Core Windows Service
在dotnet 中有topshelf 可以很方便的写windows 服务并且安装也是很方便的,命令行 运行.exe install 就直接把exe 程序安装成windows 服务.当然 代码也要做相应 ...
- Md2All
微信公众号:颜家大少欢迎关注我,一起学习,一起进步!目前,知到 Md2All 的朋友还很少,如果你觉得有帮助,希望能告诉身边有需要的朋友. 谢谢! Md2All 简介 一个Markdown在线转换工具 ...
- QQ音乐API-借他人之力实现我的音乐盒
好久没有写博客了,最近升级做爸爸了,很开心的事情.内心又很忧郁,怎么能给媳妇和儿子一个相对好的物质经济条件.现在什么都没有的我,至少还有你们. 话不多说了,这篇博客还是和自己用vue做web app相 ...
- F# 之旅(下)
写在前面的话 学习 F# 一定要去体会函数式编程的特点,推荐一下阮一峰的日志<函数式编程入门教程>. 在这篇文章中 递归函数 记录和可区分联合类型 模式匹配 可选类型 度量单位 类和接口 ...
- 【后缀数组】洛谷P3809模板题
题目背景 这是一道模板题. 题目描述 读入一个长度为 n n n 的由大小写英文字母或数字组成的字符串,请把这个字符串的所有非空后缀按字典序从小到大排序,然后按顺序输出后缀的第一个字符在原串中的位置. ...
- [整理]HTTPS和SSL证书
在互联网安全通信方式上,目前用的最多的就是https配合ssl和数字证书来保证传输和认证安全了.本文追本溯源围绕这个模式谈一谈. 名词解释 首先解释一下上面的几个名词: • https:在http(超 ...
- 模拟退火算法实例(c++ 与 c# 实现)
此片文章主要参考CSDN博主里头的一篇文章, 将自己的理解写下来,以方便后期的查阅. 一.C++ 实现 1. 已知平面上若干点坐标(xi, yi), 求平面上一点p(x, y) , 到这些点的总距离最 ...