什么是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具体解释的更多相关文章

  1. android BroadcastReceiver ACTION_TIME_TICK 系统时间监听不到

    android BroadcastReceiver ACTION_TIME_TICK 系统时间监听不到 今天做android上的消息推送,启动了一个独立service,然后在里面监听系统的ACTION ...

  2. Android slidingmenu详细解释 滑动的优化

    Android slidingmenu 详细解释 性能优化 转载请注明:   http://blog.csdn.net/aaawqqq 简单介绍 SlidingMenu 是github 上Androi ...

  3. android动画具体解释一 概述

    动画和图形概述 Android 提供了大量的强大的API以应用于UI动画和绘制2D和3D图形.以下各节向你描写叙述了这些API的预览和系统能力以帮助你决定怎么才是达到你需求的最佳方法. 动画 Andr ...

  4. android动画具体解释二 属性动画原理

    property动画是一个强大的框架,它差点儿能使你动画不论什么东西. 你能够定义一个动画来改变对象的不论什么属性,不论其是否被绘制于屏幕之上. 一个属性动画在一定时间内多次改变一个属性(对象的一个字 ...

  5. Android Scroll具体解释(二):OverScroller实战

    作者: ztelur 联系方式:segmentfault,csdn.github 本文仅供个人学习,不用于不论什么形式商业目的,转载请注明原作者.文章来源.链接,版权归原文作者全部.  本文是andr ...

  6. android动画具体解释六 XML中定义动画

    动画View 属性动画系统同意动画View对象并提供非常多比view动画系统更高级的功能.view动画系统通过改变绘制方式来变换View对象,view动画是被view的容器所处理的,由于View本身没 ...

  7. android动画具体解释四 创建动画

    使用ValueAnimator进行动画 通过指定一些int, float或color等类型的值的集合.ValueAnimator 使你能够对这些类型的值进行动画.你需通过调用ValueAnimator ...

  8. 使用Ant打包Android应用具体解释——Ant使用解析

    上篇<使用Ant打包Android应用具体解释>描写叙述了使用Ant打包的流程,但非常多步骤并没有说明如此做的原因,本篇将从Ant方面来理解,下一篇从APK生成的流程来说明. APK包的生 ...

  9. Android BroadcastReceiver 简介

    Android BroadcastReceiver 简介  在 Android 中使用 Activity, Service, Broadcast, BroadcastReceiver     活动(A ...

  10. 4、android BroadcastReceiver详细用法

    BroadcastReceiver也就是“广播接收者”的意思,顾名思义,它就是用来接收来自系统和应用中的广播. 在Android系统中,广播体现在方方面面,例如当开机完成后系统会产生一条广播,接收到这 ...

随机推荐

  1. Sync 攻击原理及防范技术

    据统计,在所有黑客攻击事件中,SYN攻击是最常见又最容易被利用的一种攻击手法.相信很多人还记得2000年YAHOO网站遭受的攻击事例,当时黑客利用的就是简单而有效的SYN攻击,有些网络蠕虫病毒配合SY ...

  2. 在使用springMVC时,我使用了@Service这样的注解,发现使用注解@Transactional声明的事务不起作用

    问题出现的场景: 在使用spring mvc时,我使用了@Service这样的注解, 发现使用注解@Transactional声明的事务不起作用. 我的配置如下: <mvc:annotation ...

  3. 如何在阿里云服务器搭建FTP服务器,在本地电脑连接并操作

    首先你需要有一个阿里云的ECS服务器 并且开通了公网宽带(话说也不贵,开来玩玩还是可以的,第一次买会比较便宜,第二次买1M的宽带两天是九毛多吧~) 开通了宽带之后,ECS服务器就可以上网了 如果嫌弃阿 ...

  4. Elasticsearch安装(四), elasticsearch head 插件安装和使用。

    安装方式如下: 一.安装Elasticsearch-Head 1.插件安装方式(推荐) #在Elasticsearch目录下 $/bin/plugin -install mobz/elasticsea ...

  5. C#与数据结构--图的遍历

    http://www.cnblogs.com/abatei/archive/2008/06/06/1215114.html 8.2 图的存储结构 图的存储结构除了要存储图中各个顶点的本身的信息外,同时 ...

  6. UI自动化测试篇 :Selenium2(Webdriver)&TestNG自动化测试环境搭建

    最开始学习UI自动化,用的工具是QTP10,用起来确实比较容易上手,自学了没多久,大家都说QTP过时了.这么好用的的工具怎么一下子就过时了呢?因为它的“笨重”,因为它作为商业软件带来的巨大使用成本,还 ...

  7. 【IOS】mac终端运行.sh文件总是提示permission denied

    如果我目录jni有一个list.sh文件 我直接 nxgametekiMacBook-Air:jni luonan$  ./list.sh ../../Classes 提示 permission de ...

  8. [LeetCode] Restore IP Address [28]

    题目 Given a string containing only digits, restore it by returning all possible valid IP address comb ...

  9. STL学习笔记(迭代器相关辅助函数)

    advance()可令迭代器前进 #include <iterator> void advance(InputIterator& pos,Dist n); 面对Random Acc ...

  10. 《Android源代码设计模式解析与实战》读书笔记

    1.定义 将对象组合成树形结构以表示"部分-总体"的层次结构,使得用户对单个对象和组合对象的使用具有一致性. 2.使用场景 (1)表示对象的部分-总体层次结构时. (2)从一个总体 ...