Android-BroadcastReceiver具体解释
什么是Broadcast
Broadcast即广播,在Android广播是很重要的功能。比如我们想在系统开机之后做某些事情、监控手机的电量、监控手机的网络状态等等。这些功能都须要用到广播。当然我们也能够自己定义广播。
自己定义广播
通常实现一个简单的自己定义广播能够通过例如以下几个步骤:
- 创建一个类继承android.content.BroadcastReceiver,并实现onReceive方法
- 在AndroidManifest.xml中注冊广播
- 通过Context的registerReceiver等方法注冊广播
- 调用Context的sendBroadcast等方法发送广播,在onReceive方法中处理广播
- 调用Context的unregisterReceiver等方法注销广播
我们通过代码来解释一下上面的步骤:
1.创建一个类继承android.content.BroadcastReceiver。并实现onReceive方法
package com.mark.broadcastreciver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
/**
* 创建一个自己定义广播接收者须要继承android.content.BroadcastReceiver,
* 并实现onReceive方法就可以。
*/
public class MyReceiver extends BroadcastReceiver {
private final static String TAG = MyReceiver.class.getSimpleName();
public MyReceiver() {
}
/**
* 当接收到广播之后会调用此方法
* @param context 上下文对象
* @param intent 调用sendBroadcast(intent)传入的Intent实例,当中包括了action、和其它附带信息
*/
@Override
public void onReceive(Context context, Intent intent) {
// 获取msg相应的数据
String msg = intent.getStringExtra("msg");
// 打印msg数据
Log.i(TAG, "msg = " + msg);
// 打印action字符串
Log.i(TAG, "action = " + intent.getAction());
}
}
2.在AndroidManifest.xml中注冊广播
<application>
<receiver android:name=".MyReceiver">
</receiver>
</application>
3.通过Context的registerReceiver等方法注冊广播
4.调用Context的sendBroadcast等方法发送广播。在onReceive方法中处理广播
5.调用Context的unregisterReceiver等方法注销广播
package com.mark.broadcastreciver;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
public class MainActivity extends AppCompatActivity {
BroadcastReceiver registerReceiver;
IntentFilter intentFilter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 创建BroadcastReceiver实例
registerReceiver = new MyReceiver();
// 创建IntentFilter。指定其action为com.mark.broadcast.receiver,这个能够自己定义
intentFilter = new IntentFilter("com.mark.broadcast.receiver");
// 注冊广播将registerReceiver与intentFilter关联,
// registerReceiver能够接收到action为com.mark.broadcast.receiver的广播
registerReceiver(registerReceiver, intentFilter);
findViewById(R.id.btnRegister).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 发送广播
// 创建Intent。指定其action为com.mark.broadcast.receiver,与registerReceiver关联的action一致
Intent intent = new Intent("com.mark.broadcast.receiver");
// 指定要发送的信息
intent.putExtra("msg", "Hello, a new message.");
sendBroadcast(intent);
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(registerReceiver);
}
}
通过上述的步骤我们就实现了一个自己定义广播,当我们点击Button在控制台中能够看到例如以下信息:
04-13 17:12:28.591 16882-16882/com.mark.broadcastreciver I/MyReceiver: msg = Hello, a new message.
04-13 17:12:28.591 16882-16882/com.mark.broadcastreciver I/MyReceiver: action = com.mark.broadcast.receiver
注冊广播
注冊广播的方式有两种:静态注冊和动态注冊。
静态注冊
这样的方法是在配置AndroidManifest.xml配置文件里注冊,通过这样的方式注冊的广播为常驻型广播,也就是说假设应用程序关闭了。有相应事件触发。程序还是会被系统自己主动调用执行。
比如:
<!-- 在配置文件里注冊BroadcastReceiver能够匹配的Intent -->
<receiver android:name=“.MyReceiver">
<intent-filter>
</action>
<action android:name=“com.mark.broadcast.reveiver”/>
<category android:name="android.intent.category.DEFAULT"></category>
</intent-filter>
</receiver>
动态注冊
这样的方法是通过代码在.Java文件里进行注冊。通过这样的方式注冊的广播为很驻型广播,即它会尾随Activity的生命周期,所以在Activity结束前我们须要调用unregisterReceiver(receiver)方法移除它。比如:
// 创建BroadcastReceiver实例
registerReceiver = new MyReceiver();
// 创建IntentFilter,指定其action为com.mark.broadcast.receiver。这个能够自己定义
intentFilter = new IntentFilter("com.mark.broadcast.receiver");
// 注冊广播将registerReceiver与intentFilter关联。
// registerReceiver能够接收到action为com.mark.broadcast.receiver的广播
registerReceiver(registerReceiver, intentFilter);
注意:假设我们在Activity中注冊了BroadcastReceiver,当这个Activity销毁的时候要主动撤销注冊否则会出现异常。方法例如以下:
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(registerReceiver);
}
广播的类型
Broadcast的类型有两种:普通广播和有序广播。
Normal broadcasts (普通广播)
Normal broadcasts是全然异步的能够同一时间被全部的接收者接收到。消息的传递效率比較高。但缺点是接收者不能讲接收的消息的处理信息传递给下一个接收者也不能停止消息的传播。多个普通广播设置同样的IntentFilter,则先注冊的先收到广播。
Ordered broadcasts (有序广播)
Ordered broadcasts的接收者依照一定的优先级进行消息的接收。
如:A,B,C的优先级依次减少。那么消息先传递给A,在传递给B,最后传递给C。
优先级别声明在中,取值为[-1000,1000]数值越大优先级别越高。优先级也可通过filter.setPriority(10)方式设置。
另外Ordered broadcasts的接收者能够通过abortBroadcast()的方式取消广播的传播,也能够通过setResultData和setResultExtras方法将处理的结果存入到Broadcast中,传递给下一个接收者。
然后,下一个接收者通过getResultData()和getResultExtras(true)接收高优先级的接收者存入的数据。
比如:
<receiver
android:name=".FirstReceiver">
<intent-filter
android:priority="999">
<action android:name="com.mark.broadcast.receiver" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<receiver android:name=".MyReceiver" >
<intent-filter
android:priority="1000">
<action android:name="com.mark.broadcast.receiver" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
如上两个receiver我们分别设置为priority为999,和1000。及时MyReceiver是后注冊的,可是其优先级比FirstReceiver高,则MyReceiver会先处理广播。
sendOrderedBroadcast 发送有序广播
sendOrderedBroadcast(intent, receiverPermission)方法接收两个參数。比普通广播的发送方式多了一个receiverPermission參数。这是一个String类型的參数,代表具有这个权限的Receiver才干处理收到此广播。假设为null则表明不要求接受者声明指定权限。我们来看一下详细的操作。
首先我们要自己定义一个权限。比如:
<permission
android:name="com.permissions.MY_BROADCAST_RECEIVER"
android:protectionLevel="normal" />
然后我们要是当前的程序具有此权限:比如:
<uses-permission android:name="com.permissions.MY_BROADCAST_RECEIVER" />
这样当前程序就拥有此权限了。
我们在发送有序广播是指定其权限为com.permissions.MY_BROADCAST_RECEIVER。注意拼写不要有错误,最好是复制过来。
发送广播例如以下:
// 创建Intent,指定其action为com.mark.broadcast.receiver,与registerReceiver关联的action一致
Intent intent = new Intent("com.mark.broadcast.receiver");
// 指定要发送的信息
intent.putExtra("msg", "Hello, a new message.");
sendOrderedBroadcast(intent, "com.permissions.MY_BROADCAST_RECEIVER");
这样我们发送广播,并指定其权限为com.permissions.MY_BROADCAST_RECEIVER,由于当前的程序已经使用了此权限了。所以当前程序中的receiver是能够接收并处理此条广播的。否则不能接收此条广播。此处的权限体现了android对安全性的重视。
sendStickyBroadcast 粘性广播
粘性广播与其它的广播方式最大的不同在于“异步”,也就是说当一个粘性广播发出去后,能够没有Receiver进行处理。可是这个广播还会一直存在,假如过了一段时间之后有Receiver注冊了此广播,则此Receiver还是能够处理这条广播的。可是细心的朋友们能够看到sendStickyBroadcast的一系列重载方法的參数中并没有上面提到的receiverPermission參数,这也将导致粘性广播在安全性上存在问题。
所以在API Level 21 上sendStickyBroadcast方法被标记为deprecated。也就是不建议我们使用粘性广播了。由于在安全性和其它方面粘性广播存在许多缺陷。这里我们也就不在重点讨论了。
总结
这里我们对广播及广播接收者进行一个简单的总结以及在使用时的一些注意事项。
1.发送广播的方法都是ContextWrapper中的方法。而Activity、Service都是ContextWrapper的子类,所以在它们中都能够发送和注冊广播
2.onReceive方法中不能做耗时操作,否则也会导致ANR
3.依据实际开发须要。尽可能为广播添加权限
4.尽可能避免使用粘性广播
5.有序广播的优先级为【-1000 ~ 1000】,数值越大。优先级越高
上述描写叙述和某些观点可能不是正解,仅供參考,欢迎大家指正、批评。
Android-BroadcastReceiver具体解释的更多相关文章
- android BroadcastReceiver ACTION_TIME_TICK 系统时间监听不到
android BroadcastReceiver ACTION_TIME_TICK 系统时间监听不到 今天做android上的消息推送,启动了一个独立service,然后在里面监听系统的ACTION ...
- Android slidingmenu详细解释 滑动的优化
Android slidingmenu 详细解释 性能优化 转载请注明: http://blog.csdn.net/aaawqqq 简单介绍 SlidingMenu 是github 上Androi ...
- android动画具体解释一 概述
动画和图形概述 Android 提供了大量的强大的API以应用于UI动画和绘制2D和3D图形.以下各节向你描写叙述了这些API的预览和系统能力以帮助你决定怎么才是达到你需求的最佳方法. 动画 Andr ...
- android动画具体解释二 属性动画原理
property动画是一个强大的框架,它差点儿能使你动画不论什么东西. 你能够定义一个动画来改变对象的不论什么属性,不论其是否被绘制于屏幕之上. 一个属性动画在一定时间内多次改变一个属性(对象的一个字 ...
- Android Scroll具体解释(二):OverScroller实战
作者: ztelur 联系方式:segmentfault,csdn.github 本文仅供个人学习,不用于不论什么形式商业目的,转载请注明原作者.文章来源.链接,版权归原文作者全部. 本文是andr ...
- android动画具体解释六 XML中定义动画
动画View 属性动画系统同意动画View对象并提供非常多比view动画系统更高级的功能.view动画系统通过改变绘制方式来变换View对象,view动画是被view的容器所处理的,由于View本身没 ...
- android动画具体解释四 创建动画
使用ValueAnimator进行动画 通过指定一些int, float或color等类型的值的集合.ValueAnimator 使你能够对这些类型的值进行动画.你需通过调用ValueAnimator ...
- 使用Ant打包Android应用具体解释——Ant使用解析
上篇<使用Ant打包Android应用具体解释>描写叙述了使用Ant打包的流程,但非常多步骤并没有说明如此做的原因,本篇将从Ant方面来理解,下一篇从APK生成的流程来说明. APK包的生 ...
- Android BroadcastReceiver 简介
Android BroadcastReceiver 简介 在 Android 中使用 Activity, Service, Broadcast, BroadcastReceiver 活动(A ...
- 4、android BroadcastReceiver详细用法
BroadcastReceiver也就是“广播接收者”的意思,顾名思义,它就是用来接收来自系统和应用中的广播. 在Android系统中,广播体现在方方面面,例如当开机完成后系统会产生一条广播,接收到这 ...
随机推荐
- espresso 元素遮挡问题。
在使用espresso进行测试的时候,点击一个横向列表的时候会在点击的项目下出现对应的横线. 实现方式是在FrameLayout下放两个TextView, 一个TextView包含下划线,默认是Fra ...
- 【spring Boot】Spring中@Controller和@RestController之间的区别
spring Boot入手的第一天,看到例子中的@RestController ............. 相同点:都是用来表示Spring某个类的是否可以接收HTTP请求 不同点:@Controll ...
- C++之纯虚函数
1. 纯虚函数形式 class Parent { public: ; }; 代码中的func1就是纯虚函数,没有函数体,没有函数的具体实现,有virtual,在函数名后面带有“ = 0”形式: 2.对 ...
- 机器学习第1课:引言(Introduction)
1.前言 Machine Learning(机器学习)是研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能. 它是人工智能的核心,是使计算机具有 ...
- python 处理抓取网页乱码问题一招鲜
FROM: http://my.oschina.net/012345678/blog/122355 相信用python的人一定在抓取网页时,被编码问题弄晕过一阵 前几天写了一个测试网页的小脚本,并查找 ...
- Selenium-java-Log4j环境搭建
1.导入Log4j 2.Build Path 3.在/src/main/resource目录下创建文件,命名为 log4j.properties 4.文件的内容是, 直接复制 ### 设置根 定义 ...
- 转: 由socket的accept说开去
from: http://ticktick.blog.51cto.com/823160/779866 今天与同学争执一个话题:由于socket的accept函数在有客户端连接的时候产生了新的socke ...
- 使用RAP搭建前端Mock Server
转载自:<前后端分离--构建前端Mock Server--windows部署rap>http://www.cnblogs.com/dothin/p/5361883.html mock:模拟 ...
- mysql double 乘法 缺失精度
CREATE TABLE tmp_decimal( id BIGINT auto_increment PRIMARY KEY , amount DOUBLE ); 创建测试表 插入测试数据 INSER ...
- 倍福TwinCAT(贝福Beckhoff)基础教程2.2 TwinCAT常见类型使用和转换_结构体
在DUTs文件夹上右击添加结构体,结构体中可以放基本变量类型,也可以嵌套其他结构体 使用的时候,需要声明结构体的实例,然后按照类.属性的格式来读写变量,会有代码的自动提示 你也可以声明数组,类 ...