前言

  Android四大组件,Activity、Service、ContentProvider、BroadcastReceiver,除了BroadcastReceiver之外,其他的在之前的博客中都有讲解到。那么,这篇博客主要讲讲BroadcastReceiver的内容。

  本文主要涉及以下几个内容:

  1. 什么是BroadcastReceiver
  2. BroadcastReceiver的种类
  3. 如何发送一个广播
  4. 如何使用BroadcastReceiver

什么是BroadcastReceiver?

  BroadcastReceiver,广播接收者,它是一个系统全局的监听器,用于监听系统全局的Broadcast消息,所以它可以很方便的进行系统组件之间的通信。

  BroadcastReceiver虽然是一个监听器,但是它和之前用到的OnXxxListener不同,那些只是程序级别的监听器,运行在指定程序的所在进程中,当程序退出的时候,OnXxxListener监听器也就随之关闭了,但是BroadcastReceiver属于系统级的监听器,它拥有自己的进程,只要存在与之匹配的Broadcast被以Intent的形式发送出来,BroadcastReceiver就会被激活。

  虽然同属Android的四大组件,BroadcastReceiver也有自己独立的声明周期,但是和Activity、Service又不同。当在系统注册一个BroadcastReceiver之后,每次系统以一个Intent的形式发布Broadcast的时候,系统都会创建与之对应的BroadcastReceiver广播接收者实例,并自动触发它的onReceive()方法,当onReceive()方法被执行完成之后,BroadcastReceiver的实例就会被销毁。虽然它独自享用一个单独的进程,但也不是没有限制的,如果BroadcastReceiver.onReceive()方法不能在10秒内执行完成,Android系统就会认为该BroadcastReceiver对象无响应,然后弹出ANR(Application No Response)对话框,所以不要在BroadcastReceiver.onReceive()方法内执行一些耗时的操作。

  如果需要根据广播内容完成一些耗时的操作,一般考虑通过Intent启动一个Service来完成该操作,而不应该在BroadcastReceiver中开启一个新线程完成耗时的操作,因为BroadcastReceiver本身的生命周期很短,可能出现的情况是子线程还没有结束,BroadcastReceiver就已经退出的情况,而如果BroadcastReceiver所在的进程结束了,该线程就会被标记为一个空线程,根据Android的内存管理策略,在系统内存紧张的时候,会按照优先级,结束优先级低的线程,而空线程无异是优先级最低的,这样就可能导致BroadcastReceiver启动的子线程不能执行完成。

  

BroadcastReceiver的种类

  上面提到,当系统以一个Intent的形式发送一个Broadcast出去之后,所有与之匹配的BroadcastReceiver都会被实例化,但是这里是有区别的,根据Broadcast的传播方式区别,在系统中有如下两种Broadcast:

  • 普通广播:Normal Broadcase,它是完全异步的,也就是说,在逻辑上,当一个Broadcast被发出之后,所有的与之匹配的BroadcastReceiver都同时接收到Broadcast。优点是传递效率比较高,但是也有缺点,就是一个BroadcastReceiver不能影响其他响应这条Broadcast的BroadcastReceiver。
  • 有序广播:Ordered Broadcast,它是同步执行的,也就是说有序广播的接收器将会按照预先声明的优先级依次接受Broadcast,是链式结构,优先级越高(-1000~1000),越先被执行。因为是顺序执行,所有优先级高的接收器,可以把执行结果传入下一个接收器中,也可以终止Broadcast的传播(通过abortBroadcast()方法),一旦Broadcast的传播被终止,优先级低于它的接收器就不会再接收到这条Broadcast了。

  虽然系统存在两种类型的Broadcast,但是一般系统发送出来的Broadcast均是有序广播,所以可以通过优先级的控制,在系统内置的程序响应前,对Broadcast提前进行响应。这就是市场上一些拦截器类(如:短信拦截器、电话拦截器)的软件的原理。

如何发送一个广播

  上面已经介绍了系统中两种不同的Broadcast,而根据Broadcast传播的方式,Context提供了不同的方法来发布它们:

  • sendBroadcast():发送普通广播。
  • sendOrderedBroadcast():发送有序广播。

  以上两个方法都有多个重载方法,根据不同的场景使用,最简单的莫过于直接传递一个Intent来发送一个广播。

如何使用BroadcastReceiver

  BroadcastReceiver本质上还是一个监听器,所以使用BroadcastReceiver的方法也是非常简单,只需要继承BroadcastReceiver,在其中重写onReceive(Context context,Intent intent)即可。一旦实现了BroadcastReceiver,并部署到系统中后,就可以在系统的任何位置,通过sendBroadcast、sendOrderedBroadcast方法发送Broadcast给这个BroadcastReceiver。

  但是仅仅继承BroadcastReceiver和实现onReceive()方法是不够的,同为Android系统组件,它也必须在Android系统中注册,注册一个BroadcastReceiver有两种方式:

  • 在代码中使用Content.registerReceiver(BroadcastReceiver receiver, IntentFilter filter)进行注册,在使用完毕使用Content.unregisterReceiver(BroadcastReceiver receiver)方法进行注销。
  • 使用清单文件AndroidManifest.xml注册,在<application/>节点中,使用<receiver/>节点注册,并用android:name属性中指定注册的BroadcastReceiver对象,一般还会通过<Intent-filter/>指定<action/>和<category/>,并在<Intent-filter/>节点中通过android:priority属性设置BroadcastReceiver的优先级,在-1000~1000范围内,数值越到优先级越高。

  虽然Android系统提供了两种方式注册BroadcastReceiver,但是一般在实际开发中,还是会使用清单文件进行注册:

         <receiver android:name="cn.bgxt.Broadcastdemo.Basic.BasicBroadcast">
<intent-filter android:priority="100">
<action android:name="cn.bgxt.Broadcastdemo.Basic.broadcast"/>
</intent-filter>
</receiver>

  下面通过一个简单的示例,讲解一下BroadcastReceiver的声明,以及如何向这个BroadcastReceiver发送消息。

  首先先声明一个BroadcastReceiver,BasicBroadcast.java:

 package cn.bgxt.Broadcastdemo.Basic;

 import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast; public class BasicBroadcast extends BroadcastReceiver { @Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,
"接收到Broadcast,消息为:" + intent.getStringExtra("msg"),
Toast.LENGTH_SHORT).show();
}
}

   再声明一个Activity,用于发送Broadcast:BasicActivity.java: 

 package cn.bgxt.Broadcastdemo.Basic;

 import com.bgxt.datatimepickerdemo.R;

 import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button; public class BasicActivity extends Activity {
Button btnBasicSendNormal, btnBasicSendOrdered; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_basic); btnBasicSendNormal = (Button) findViewById(R.id.btnBasicSendNormal);
btnBasicSendOrdered = (Button) findViewById(R.id.btnBasicSendOrdered);
btnBasicSendNormal.setOnClickListener(new View.OnClickListener() { @Override
public void onClick(View v) {
Intent broadcast=new Intent();
broadcast.setAction("cn.bgxt.Broadcastdemo.Basic.broadcast");
broadcast.putExtra("msg", "这是一个普通广播");
sendBroadcast(broadcast);
}
}); btnBasicSendOrdered.setOnClickListener(new View.OnClickListener() { @Override
public void onClick(View v) {
Intent broadcast=new Intent();
broadcast.setAction("cn.bgxt.Broadcastdemo.Basic.broadcast");
broadcast.putExtra("msg", "这是一个有序广播");
sendOrderedBroadcast(broadcast, null);
}
});
}
}

  效果展示:

  源码下载

总结

  这篇博客已经简要说明了BroadcastReceiver的使用以及需要注意的地方。但是一般实际项目中,很少自己定制Broadcast去使用,大多数情况下是去拦截系统发布的Broadcast,针对系统发布的Broadcast内容来做相应的操作。Android系统中原生定义了很多广播的内容,如:开机、关机、来电、短信等等一些系统状态的变化的Broadcast。但是关于系统Broadcast的内容,不在本篇博客内,之后再慢慢详细介绍。

Android--广播BroadcastReceiver的更多相关文章

  1. Android 广播 BroadcastReceiver

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

  2. Android广播BroadcastReceiver 二

    BroadcastReceiver: 在Android中,Broadcast是一种广泛运用的在应用程序之间传输信息的机制.而BroadcastReceiver是对发送出来的 Broadcast进行过滤 ...

  3. Android广播BroadcastReceiver 一

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

  4. Android广播BroadcastReceiver

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

  5. 035 Android 广播(BroadCastReceiver)

    1.介绍 2.实现方法 3.注册广播 (1)静态广播 在AndroidManifest.xml文件中注册广播 <intent-filter>为过滤器 <receiver androi ...

  6. Android中BroadcastReceiver广播

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

  7. Android - 广播接收者 - BroadcastReceiver

    BroadcastReceiver 介绍: 广播是一种广泛运用的在应用程序之间传输信息的机制 .而 BroadcastReceiver 是对发送出来的广播 进行过滤接收并响应的一类组件 接受一种或者多 ...

  8. Android笔记(二十六) Android中的广播——BroadcastReceiver

    为了方便进行系统级别的消息通知,Android有一套类似广播的消息机制,每个应用程序都可以对自己感兴趣的广播进行注册,这样该程序就只会接收自己所关心的广播内容,这些广播可能是来自于系统,也可能是来自于 ...

  9. Android(java)学习笔记172:BroadcastReceiver之 Android广播机制

    Android广播机制 android系统中有各式各样的广播,各种广播在Android系统中运行,当"系统/应用"程序运行时便会向Android注册各种广播.Android接收到广 ...

  10. (八)Android广播接收器BroadcastReceiver

    一.使用Broadcast Reciver 1.右击java文件夹,new->other->Broadcast Receiver后会在AndroidManifest.xml文件中生成一个r ...

随机推荐

  1. 计算任意位数的Pi

    当用程序实现求pi的值时,也许你能够很快写出算法(利用求pi的几个公式),但是由于使用单变量保存结果,限于计算机硬件对变量的表示范围有限,因此,最多只能计算出pi值小数点后十多位.但需要得到一个更大位 ...

  2. PHP 函数的“引用返回”概念释疑(转)

    很多时候我们会看到这样的代码(出自 CI 框架源码): 1 $class =& load_class('a','b'); 我们都知道其中的'&'是指引用,但是它的作用是什么呢?它能够解 ...

  3. 几种任务调度的 Java 实现方法与比较--转载

    前言 任务调度是指基于给定时间点,给定时间间隔或者给定执行次数自动执行任务.本文由浅入深介绍四种任务调度的 Java 实现: Timer ScheduledExecutor 开源工具包 Quartz ...

  4. 1_Linux_目录简介

    1. Linux中所以内容以文件形式保存,包括硬件,所以在用命令行配置文件时,该配置仅仅是临时生效.   2. Linux不靠扩展名区分类型,而是靠文件权限.之所以有扩展名是为了便于管理. .rpm二 ...

  5. iOS图片拉伸

    常用的图片拉伸场景有:聊天页面的气泡,需要根据内容拉伸,但圆角拉伸后会变形,为避免圆角拉伸,可以指定拉伸区域.UIImage实体调用以下方法即可指定拉伸区域. - (UIImage *)stretch ...

  6. android SDK开发 -- TitleBar封装(一)

    假设app的title 统一的都是这种左中右结构的 代码如下 <LinearLayout xmlns:android="http://schemas.android.com/apk/r ...

  7. Centos7+Apache2.4+php5.6+mysql5.5搭建Lamp环境——为了wordPress

    最近想搭建个人博客玩玩,挑来挑去发现口碑不错的博客程序是wordpress,简称wp.虽然是学java路线的程序员,但因入行时间太短,至今没有发现较为称手开源的博客程序,如果各位大神有好的推荐,也希望 ...

  8. Mysql 列转行group_concat函数,与行转列

    1.正常情况. SELECT JoinEventIds from nt_mainnum 2.使用group_concat函数 select group_concat(JoinEventIds) fro ...

  9. 一些iOS笔试题目

    1.什么是arc?(arc是为了解决什么问题诞生的?) 首先解释ARC: automatic reference counting自动引用计数. ARC几个要点: 在对象被创建时 retain cou ...

  10. C# 深入浅出 委托与事件

    C#中的委托和事件的概念接触很久了,但是一直以来总没有特别透彻的感觉,现在我在这里总结一下: 首先我们要知道委托的由来,为什么要使用委托了? 我们先看一个例子: 假设我们有这样一个需求,需要计算在不同 ...