BroadcastReceiver的作用:

BroadcastReceiver,是和Intent有很大关系的Android组件。

Android中的 Intent 可以用来:

  1. 在应用程序内部和应用程序之间传递数据(传输信息的机制),以及通过监听Intent来检测到系统状态的变化;

  2. 启动Activity和Service;

  3. Broadcast Intent用来在系统范围内公布应用程序事件。

Broadcast Intent用于在系统范围内广播应用程序事件,而BroadcastReceiver则用于接收或监听Intent事件,对发出的Broadcast进行过滤、接受并响应的一类组件(发送通知,更新UI或者数据,应用程序间相互通信,监听系统状态;比如开机,网络等)。上述两者的作用,恰好是相反的。

在Android系统中,广播体现在方方面面,例如当开机完成后系统会产生一条广播,接收到这条广播就能实现开机启动服务的功能;当网络状态改变时系统会产生一条广播,接收到这条广播就能及时地做出提示和保存数据等操作;当电池电量改变时,系统会产生一条广播,接收到这条广播就能在电量低时告知用户及时保存进度,等等。

BroadcastReceiver包括两个概念,广播发送者和广播接收者(Receiver),这里的广播实际就是指Intent;应用程序可以自己发送广播自己接收,也可以接受系统或其他应用的广播或是发送广播给其他应用程序。当发送者发送某个广播时,系统会将发送的广播(Intent)与系统中所有注册的符合条件的接收者(Receiver) 的IntentFilter进行匹配。若匹配成功,则执行相应接收者的onReceive(),匹配规则见Intent和IntentFilter的匹配规则。

“Android中的广播机制设计的非常出色,很多事情原本需要开发者亲自操作的,现在只需等待广播告知自己就可以了,大大减少了开发的工作量和开发周期。”

BroadcastReceiver的使用方法:

要使用Broadcast Receiver能够接收广播,就需要对其进行注册,既可以使用代码,也可以在应用程序的manifest文件中注册(此时称为manifest接收器)。无论怎么注册,都需要使用一个Intent Filter来指定要监听哪些Intent(特指:Intent的Action)和数据。

对于包含manifest接收器的应用程序,在Intent被广播出去的时候,应用程序不一定非要处于运行状态才能执行接收(而对于在代码中注册的接收器只会在包含它的应用程序组件运行时才会响应Broadcast Intent)。当匹配的Intent被广播出去的时候,它们会被自动地启动。

对于资源管理来说,这一点是非常优秀的,因为它提供了一种能够创建出事件驱动型的应用程序机制(不仅可以接受应用程序自定义的广播,还可以接受系统级别的广播)。即使应用程序被关闭或者销毁了,也仍然能够对广播事件作出响应。

1. 静态注册广播接受者

public class DemoBroadcastReceiver extends BroadcastReceiver {

    @Override
public void onReceive(Context context, Intent intent) {
String msg = intent.getStringExtra("msg");
Log.d(Constanst.TAG, "DemoBroadcastReceiver::"+msg);
}
}

对应的要到AndroidManifest.xml文件中进行注册:

<receiver android:name=".DemoBroadcastReceiver">
<intent-filter>
<action android:name="com.androidiot.demo.DEMO.TEST"></action>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</receiver>

2. 动态注册广播

@Override
protected void onStart() {
super.onStart(); // TODO 此处注册广播监听
receiver = new MyBroadReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(Constanst.ACTION);
MainActivity.this.registerReceiver(receiver, filter);
}

此处是在Activity中的onStart()中注册广播,与此对应的,需要在onPause()中取消广播监听:

@Override
protected void onPause() {
super.onPause();
// TODO 此处取消广播监听
if (receiver != null) {
unregisterReceiver(receiver);
receiver = null;
}
}

对于自己发送和接受的广播可以通过registerReceiver注册,对于系统常用广播的接收通常用<receiver>标签注册。registerReceiver可以手动控制,所以适当的注册和取消注册能节省系统资源,<receiver>标签系统开机后一直有效。

BroadcastReceiver在onReceive()执行结束后即表示生命周期结束,所以不适合在onReceive中做绑定服务操作;结束后若某个进程只含有该BroadcastReceiver,则优先级将降低可能被系统回收,所以BroadcastReceiver中不适合做一些异步操作,如新建线程下载数据,BroadcastReceiver结束后可能在异步操作完成前进程已经被系统kill。同时由于ANR限制BroadcastReceiver的onReceive()必须在5秒内完成,而且onReceive()默认会在主线程中执行,所以BroadcastReceiver中不适合做一些耗时操作,对于耗时操作需要交给service处理,比如网络或数据库耗时操作、对话框的显示(因为现实时间可能超时,用Notification代替)。

BroadcastReceiver的类型:

Android中的广播类型分为两种:无序广播和有序广播;前者为异步的,也就是大致实现了同一时间接收到广播,不分先后顺序;后者根据接受者的优先级别,实现广播的先后接受。

无序广播的各个接受者,无法做到停止广播的传递;有序广播中,优先接收到广播的接受者可以实现终止广播的传递(并且可以改变传递的Extras的内容)。

BroadcastReceiver的使用注意事项:

对于接收到指定广播的onReceive(),必须在5s内执行完毕;否则会出现ANR。

一般情况下,Broadcast Receiver将会更新内容、启动Servicee、更新UI,或者使用Notification Manager来通知用户。5秒的执行限制保证了主要的处理工作不能够、也不应该由Broadcast Receiver直接完成。

BroadcastReceiver的设计初衷就是从全局考虑的,可以方便应用程序和系统、应用程序之间、应用程序内的通信,所以对单个应用程序而言BroadcastReceiver是存在安全性问题的,相应问题及解决如下:

a、当应用程序发送某个广播时系统会将发送的Intent与系统中所有注册的BroadcastReceiver的IntentFilter进行匹配,若匹配成功则执行相应的onReceive函数。可以通过类似sendBroadcast(Intent, String)的接口在发送广播时指定接收者必须具备的permission。或通过Intent.setPackage设置广播仅对某个程序有效。

b. 当应用程序注册了某个广播时,即便设置了IntentFilter还是会接收到来自其他应用程序的广播进行匹配判断。对于动态注册的广播可以通过类似registerReceiver(BroadcastReceiver, IntentFilter, String, android.os.Handler)的接口指定发送者必须具备的permission,对于静态注册的广播可以通过android:exported="false"属性表示接收者对外部应用程序不可用,即不接受来自外部的广播。

c.上面两个问题其实都可以通过LocalBroadcastManager来解决,LocalBroadcastManager只会将广播限定在当前应用程序中。LocalBroadcastManager局部广播管理器,包含在Android Support Library中,局部广播的作用域要小,使用局部广播管理器比发送全局广播更加有效,也确保了应用程序外部的任何组件都收不到广播的Intent,不会有私人数据或敏感数据泄露出去。类似的,其他的应用程序也不能向你的接收器发送广播,避免了这些接收器成为安全漏洞。

Android的BroadcastReceiver组件的更多相关文章

  1. Android中BroadcastReceiver组件具体解释

    Android系统的4个组件最终还剩一种组件了BroadcastReceiver,这个组件是全局监听器,能够监听系统全局的广播消息,能够方便的实现系统中不同组件之间的通信 BroadcastRecei ...

  2. Android学习(十三) BroadcastReceiver组件(广播)

    一.Broadcast(广播) 是一种广泛应用在应用程序之间传输信息的机制. 二.Broadcast(广播接收器) 是对发送出来的广播进行过滤接收并响应的一类组件,它就是用来接收来自系统和应用中的广播 ...

  3. android BroadcastReceiver组件简单的使用

    1.清单文件 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android=& ...

  4. Android中BroadcastReceiver的两种注册方式(静态和动态)详解

    今天我们一起来探讨下安卓中BroadcastReceiver组件以及详细分析下它的两种注册方式. BroadcastReceiver也就是"广播接收者"的意思,顾名思义,它就是用来 ...

  5. Android消息传递之组件间传递消息

    前言: 上篇学习总结了Android通过Handler消息机制实现了工作线程与UI线程之间的通信,今天来学习一下如何实现组件之间的通信.本文依然是为学习EventBus做铺垫,有对比才能进步,今天主要 ...

  6. Android的四大组件之Activity

    Android的四大组件之Activity Activity:是Android组件中最基本也是最为常见用的四大组件(Activity,Service服务,Content Provider内容提供者,B ...

  7. Android 广播 BroadcastReceiver

    Android 系统里定义了各种各样的广播,如电池的使用状态,电话的接收和短信的接收,开机启动都会产生一个广播.当然用户也可以自定义自己的广播. 既然说到广播,那么必定有一个广播发送者,以及广播接收器 ...

  8. Android四大基本组件介绍与生命周期

    Android四大基本组件介绍与生命周期 Android四大基本组件分别是Activity,Service服务,Content Provider内容提供者,BroadcastReceiver广播接收器 ...

  9. Android中BroadcastReceiver广播

    BroadCastReceiver 简介 广播接收者( BroadcastReceiver )用于接收广播 Intent ,广播 Intent 的发送是通过调用 Context.sendBroadca ...

随机推荐

  1. codeforces-1140 (div2)

    A.维护一个前缀最大值,不断跳即可 #include <map> #include <set> #include <ctime> #include <cmat ...

  2. Git 分支(一)简介&创建分支

    理解Git暂存区 文件.git/index是一个包含文件索引的目录树,像是一个虚拟的工作区.在这个虚拟工作区的目录树中,记录了文件名和文件的状态信息.以便快速检测文件的变化.              ...

  3. 一个select元素自定义设计的新思路:appearance: none之后利用<>符号制造小箭头

    最近工作时解决了一个前端小问题(如下图所示):在Safari中,select的控件之上有不和谐的灰色部分. 刚开始时我以为是backgrand或是border设置不当之类产生的问题,在搜索了很久之后终 ...

  4. 算法第四版Question

    1.ECLIPES标准输入流 ①Run As-->Run Configurations-->Commom-->Input File在Input File里面输入要读取的文本文件 这对 ...

  5. Correction suggestions

    1. title: A remark on the global existence of weak solutions to the compressible quantum Navier-Stok ...

  6. Windows系统下查看某一进程下所有线程的dos命令

    1.查看进程 pslist或 tasklist 注:若出现“pslist不是外部或内部命令,也不是可运行的程序....”,需要去TechNet官网下载psTools(链接https://technet ...

  7. Leetcode#13. Roman to Integer(罗马数字转整数)

    题目描述 罗马数字包含以下七种字符:I, V, X, L,C,D 和 M. 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000 例如, 罗马数字 2 写做 II ,即 ...

  8. Eclipse中的sysout与debug-遁地龙卷风

    (-1)调试 在读<<一个程序员的奋斗史>>时里面提到这是一件很low的事情,突然想到自己也一直用sysout, 我是一个有情怀的人! (0)sysout的坏处 之所以长久的使 ...

  9. php7 + 新特性 部分

    三目运算符: 以前:$type = isset($_GET['type']) ? $_GET['type'] : '测试'; php7.0: $type = $_GET['type'] ?? '测试' ...

  10. 使用pytesseract出现的问题

    dyld: Library not loaded: /usr/local/opt/jpeg/lib/libjpeg.8.dylib Referenced from: /usr/local/lib/li ...