本来想自己写一篇的,不过看到一篇讲的很详细的,这里我就转载一下分享

BroadcastReceiver(广播接收器)是Android中的四大组件之一。
        下面是Android Doc中关于BroadcastReceiver的概述:
        ①广播接收器是一个专注于接收广播通知信息,并做出对应处理的组件。很多广播是源自于系统代码的──比如,通知时区改变、电池电量低、拍摄了一张照片或者用户改变了语言选项。应用程序也可以进行广播──比如说,通知其它应用程序一些数据下载完成并处于可用状态。
        ②应用程序可以拥有任意数量的广播接收器以对所有它感兴趣的通知信息予以响应。所有的接收器均继承自BroadcastReceiver基类。
        ③广播接收器没有用户界面。然而,它们可以启动一个activity来响应它们收到的信息,或者用NotificationManager来通知用户。通知可以用很多种方式来吸引用户的注意力──闪动背灯、震动、播放声音等等。一般来说是在状态栏上放一个持久的图标,用户可以打开它并获取消息。
Android中的广播事件有两种,一种就是系统广播事件,比如:ACTION_BOOT_COMPLETED(系统启动完成后触发),ACTION_TIME_CHANGED(系统时间改变时触发),ACTION_BATTERY_LOW(电量低时触发)等等。另外一种是我们自定义的广播事件。
        广播事件的流程
        ①注册广播事件:注册方式有两种,一种是静态注册,就是在AndroidManifest.xml文件中定义,注册的广播接收器必须要继承BroadcastReceiver;另一种是动态注册,是在程序中使用Context.registerReceiver注册,注册的广播接收器相当于一个匿名类。两种方式都需要IntentFIlter。
        ②发送广播事件:通过Context.sendBroadcast来发送,由Intent来传递注册时用到的Action。
        ③接收广播事件:当发送的广播被接收器监听到后,会调用它的onReceive()方法,并将包含消息的Intent对象传给它。onReceive中代码的执行时间不要超过5s,否则Android会弹出超时dialog。

Broadcast Receiver接收系统自带的广播
我们做一个例子,功能是在系统启动时播放一首音乐。
1、建立一个项目Lesson21_BroadcastReceiver,拷贝一首音乐进res/raw目录
2、建立HelloBroadcastReceiver.java 内容如下:

[java] view plaincopy
  1. <span style="font-size:14px;">Codepackage android.basic.lesson21;
  2. import android.content.BroadcastReceiver;
  3. import android.content.Context;
  4. import android.content.Intent;
  5. import android.media.MediaPlayer;
  6. import android.util.Log;
  7. public class HelloBroadReciever extends BroadcastReceiver {
  8. //如果接收的事件发生
  9. @Override
  10. public void onReceive(Context context, Intent intent) {
  11. //则输出日志
  12. Log.e("HelloBroadReciever", "BOOT_COMPLETED!!!!!!!!!!!!!!!!!!!!!!!!!");
  13. Log.e("HelloBroadReciever", ""+intent.getAction());
  14. //则播放一首音乐
  15. MediaPlayer.create(context, R.raw.babayetu).start();
  16. }
  17. }
  18. </span>

3、在AndroidManifest.xml中注册此Receiver :

[html] view plaincopy
  1. <span style="font-size:14px;"><?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionname="1.0" android:versioncode="1" package="android.basic.lesson21">
  3. <application android:icon="@drawable/icon" android:label="@string/app_name">
  4. <activity android:label="@string/app_name" android:name=".MainBroadcastReceiver">
  5. <intent -filter="">
  6. <action android:name="android.intent.action.MAIN">
  7. <category android:name="android.intent.category.LAUNCHER">
  8. </category></action></intent>
  9. </activity>
  10. <!-- 定义Broadcast Receiver 指定监听的Action -->
  11. <receiver android:name="HelloBroadReciever">
  12. <intent -filter="">
  13. <action android:name="android.intent.action.BOOT_COMPLETED">
  14. </action></intent>
  15. </receiver>
  16. </application></manifest>  </span>

4、发布程序,启动模拟器,可以在Logcat中看到: 

同时能听到音乐播放的声音。说明我们确实接收到了系统启动的广播事件,并做出了响应。

自定义广播
下面我们学习自己制作一个广播。我们接着刚才的例子,继续写下去。
5、在MainBroadcastReceiver.java中填写如下代码:

[java] view plaincopy
  1. Codepackage android.basic.lesson21;
  2. import android.app.Activity;
  3. import android.content.Intent;
  4. import android.os.Bundle;
  5. import android.view.View;
  6. import android.widget.Button;
  7. public class MainBroadcastReceiver extends Activity {
  8. /** Called when the activity is first created. */
  9. @Override
  10. public void onCreate(Bundle savedInstanceState) {
  11. super.onCreate(savedInstanceState);
  12. setContentView(R.layout.main);
  13. Button b1 = (Button) findViewById(R.id.Button01);
  14. b1.setOnClickListener(new View.OnClickListener() {
  15. @Override
  16. public void onClick(View v) {
  17. //定义一个intent
  18. Intent intent = new Intent().setAction(
  19. "android.basic.lesson21.Hello").putExtra("yaoyao",
  20. "yaoyao is 189 days old ,27 weeks -- 2010-08-10");
  21. //广播出去
  22. sendBroadcast(intent);
  23. }
  24. });
  25. }
  26. }

6、更改 HelloBroadReceiver.java 内容如下:

[java] view plaincopy
  1. Codepackage android.basic.lesson21;
  2. import android.content.BroadcastReceiver;
  3. import android.content.Context;
  4. import android.content.Intent;
  5. import android.media.MediaPlayer;
  6. import android.util.Log;
  7. public class HelloBroadReciever extends BroadcastReceiver {
  8. //如果接收的事件发生
  9. @Override
  10. public void onReceive(Context context, Intent intent) {
  11. //对比Action决定输出什么信息
  12. if(intent.getAction().equals("android.intent.action.BOOT_COMPLETED")){
  13. Log.e("HelloBroadReciever", "BOOT_COMPLETED !!!!!!!!!!!!!!!!!!!!!!!!!");
  14. }
  15. if(intent.getAction().equals("android.basic.lesson21.Hello")){
  16. Log.e("HelloBroadReciever", "Say Hello to Yaoyao !!!!!!!!!!!!!!!!!!!!!!!!!");
  17. Log.e("HelloBroadReciever", intent.getStringExtra("yaoyao"));
  18. }
  19. //播放一首音乐
  20. MediaPlayer.create(context, R.raw.babayetu).start();
  21. }
  22. }

7、更改 AndroidManifest.xml 内容如下:

[html] view plaincopy
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android.basic.lesson21" android:versionname="1.0" android:versioncode="1">
  3. <application android:icon="@drawable/icon" android:label="@string/app_name">
  4. <activity android:label="@string/app_name" android:name=".MainBroadcastReceiver">
  5. <intent -filter="">
  6. <action android:name="android.intent.action.MAIN">
  7. <category android:name="android.intent.category.LAUNCHER">
  8. </category></action></intent>
  9. </activity>
  10. <!-- 定义Broadcast Receiver 指定监听的Action 这里我们的接收器,接收了2个Action,一个系统的一个我们自定义的  -->
  11. <receiver android:name="HelloBroadReciever">
  12. <intent -filter="">
  13. <action android:name="android.intent.action.BOOT_COMPLETED">
  14. </action></intent>
  15. <intent -filter="">
  16. <action android:name="android.basic.lesson21.HelloYaoYao">
  17. </action></intent>
  18. </receiver>
  19. </application>
  20. <uses -sdk="" android:minsdkversion="8">
  21. </uses></manifest>

8、运行程序,点击按钮,查看LogCat,听听声音


在使用Broadcast 时我们应该注意到,BroadcastReceiver的子类别都是无状态的类别,每次收到发送广播事件后,BroadcastReceiver都会创建一个新的对象,然后再执行onReceive()函数,当onReceive()函数执行完毕后,就立刻删掉该对象,下一次再收到此广播后,又会创建一个新的对象。所以说Broadcast组建是Android中最轻薄、最短小的组建。我们增加了一个static的变量numStatic ,和num变量 。代码如下:

[java] view plaincopy
  1. package com.androidtest.broadcaster;
  2. import android.content.BroadcastReceiver;
  3. import android.content.Context;
  4. import android.content.Intent;
  5. import android.util.Log;
  6. /**
  7. * ClassName:Broadcaster
  8. * Function: TODO ADD FUNCTION
  9. * Reason:   TODO ADD REASON
  10. *
  11. * @author   Leon
  12. * @version
  13. * @since    Ver 1.1
  14. * @Date     2011-6-9
  15. */
  16. public class Broadcaster extends BroadcastReceiver{
  17. private  static  final  String TAG = "Broadcaster";
  18. private  static  int  numStatic  =100 ;
  19. private  int  num =100 ;
  20. @Override
  21. public void onReceive(Context context, Intent intent) {
  22. // TODO Auto-generated method stub
  23. String string = intent.getAction();
  24. numStatic= numStatic+50;
  25. num=100+50;
  26. Log.v(TAG  , "The action is "+ string + "Static Number is :" + numStatic
  27. + " Object num is :" + num);
  28. }
  29. }

多次发送广播,然后输出的结果如下,我们可以看到static Number 每次执行都会增加,而Object Num因为每次都要创建所以一直都是一个固定的值。

上文中提到了BroadcastReceiver是Android中最轻薄、最短小的组件,它的对象生命周期十分短暂,经过傻蛋测试在BroadcastReceiver中让线程睡眠10秒(Activity是5秒钟)的话,Android就会弹出错误(和Activity超时的错误相同),同时需要注意的是Activity、Service和BroadcastReceiver都是运行在本进程的主线程里面的。通过这个测试让傻蛋进一步产生了疑问,如果在Service中处理一个长时间的任务会怎么样?
        启动一个Service,然后在Service的onCreate()方法中添加如下代码:

[java] view plaincopy
  1. try {
  2. Log.v(TAG , "sleep start …..");
  3. Thread.sleep(20000);
  4. Log.v(TAG,"sleep end …..");
  5. } catch (InterruptedException e) {
  6. / / TODO Auto-generated catch block
  7. e.printStackTrace();
  8. }

很简单就是让Service睡眠20秒钟,我们会发现,sleep start…. 和 sleep end….这两个日志打印出来了,但是后台还会出现如下错误,前台弹出no response超时对话框。

在onCreate()中新启动一个线程来,睡眠时,程序正常。
      所以总结一下:无论是 Activity、BroadcastReceiver还是Service,只要是有长时间处理的任务,就需要重新开一个线程来处理,为什么会这样?因为他们都是运行在主线程中的。
       在使用BroadcastReceiver时还有一个我们需要注意的:在BroadcastReceiver的onReceive(Context context , Intent intent )这第一个context到底是哪一个context?是Activity还是Application?通过测试发现:
如果你的BroadcastReceiver是通过在Activity中的this.registerReceiver(myBroadcaster, filter); 来注册的话,那么这个context就是这个Activity,而如果是通过AndroidManifest来注册的话,那么这个context就是:android.app.ReceiverRestrictedContext。

BroadcastReceiver是接收从sendBroadcast()发出的intent的基类。你可以通过Context.registerReceiver()方法在代码中动态的注册一个BroadcastReceiver的实例,也可以通过再AndroidManifest.xml文件中用<receiver>标签来静态声明。
       注意:如果你实在Activity.onResume()方法中注册的一个receiver,那么你必须在Activity.onPause()方法中进行注销。(当一个activity处于暂停状态是不会接收intents的,并且这样做也可以减小系统不必要的开销)。不要在Activity.onSaveInstanceState()方法中注销receiver,因为activity从栈中恢复的时候并不会调用这个方法了。
       可以接收的broadcast主要分为两种类型:
      普通的broadcasts(通过Context.sendBroadcast发送)是完全异步的。这个broadcast的receiver以无序的状态运行,经常是在同一时刻运行。这种做法是十分高效的,但是也意味着receiver不能够利用相互处理的结果或者是调用退出的API来退出(因为不知道哪个receiver先接收到intent)。
      有序的broadcasts(通过Context.sendOrderedBroadcast发送)一次只发送给一个receiver。每一个receiver是有序的处理这个intent的,前面的receiver可以传递结果给下一个receiver,或者任意一个receiver都可以完全的退出,这样intent就不会传递给其他的receivers.receiver的执行顺序可以通过匹配的intent-filter中的android:priority属性来控制;如果有多个receivers处于同一个优先级,那么这几个receivers将会以任意的顺序来执行。
      即使是在广播普通的broadcasts的情况下,系统也有可能在某些情况下转换为一次发送一个broadcast给一个receriver。特别是当receivers需要创建进程时,在同一时刻仅仅一个receiver可以运行,避免系统因为这些新建的进程而过载。
      注意:尽管Intent类是用来发送和接受这些broadcasts,这里的Intent broadcast机制和那些通过Context.startActivity()方法来启动activity的intent是完全独立的。一个BroadcastReceiver是没办法观察和捕获一个用于启动activity的intent的;同样的,当你通过intent来发出broadcast时,你也不可能(通过这个intent)找到或者启动一个activity的。这两种操作是完全不同的:通过一个intent来启动一个activity是一个前台操作,会改变用户当前交互的对象;而通过intent来发出broadcast是一个后台操作,用户经常是察觉不到的。
      BroadcastReceiver类(通过一个manifest的<receiver>标签作为一个组件启动)是应用程序全局声明周期重要的一部分。

讨论的主题
   1、Receiver的生命周期
   2、权限
   3、进程的生命周期
  
开发者指南
   更详细的关于如何获取和解析一个Intent的内容,请详见Intents and Intent Filters开发者指南
  
Receiver的生命周期
       一个BroadcastReceiver的对象仅仅在调用onReceiver(COntext, Intent)的时间中有效。一旦你的代码从这个函数中返回,那么系统就认为这个对象应该结束了,不能再被激活。
      你在onReceive(Context, Intent)中的实现有着非常重要的影响:任何对于异步操作的请求都是不允许的,因为你可能需要从这个函数中返回去处理异步的操作,但是在那种情况下,BroadcastReceiver将不会再被激活,因此系统就会再异步操作之前杀死这个进程。
      特别是,你不应该再一个BroadcastReceiver中显示一个对话框或者绑定一个服务。对于前者(显示一个对话框),你应该用NotificationManagerAPI来替代,对于后者(绑定一个服务),你可以使用Context.startService()发送一个命令给那个服务来实现绑定效果。
权限
     存取的权限可以通过在发送方的Intent或者接收方的Intent中强制指定。
     在发送一个broadcast时强制指定权限,就必须提供一个非空的peemission参数给sendBroadcast(Intent, String)或者是sendOrderedBroadcast(Intent, String, BroadcastReceiver, android.os.Handel, int, String, Bundle).只有那些拥有这些权限(通过在ANdroidManifest.xml文件中相应的声明<uses-permission>标签)的receiver能够接收这些broadcast。
      在接收一个broadcast时强制指定权限,就必须在注册receiver时提供一个非空的permission参数--无论是在调用registerReceiver(BroadcastReceiver, IntentFilter, String, android.os.Handler)或者是通过再AndroidManifest.xml文件中通过<receiver>静态标签来声明。只有那些拥有这些权限(通过在相应的AndroidManifest.xml文件中查询<uses-permission>标签来获知)的发送方将能够给这个receiver发送Intent。
      对于安全和权限的详细内容请查看Security and Permission文档。
进程的生命周期
      一个正在执行BroadcastReceiver(也就是,正在执行onReceive(COntext, Intent)方法)的进程被认为是一个前台的进程,将会一直运行,除非系统处于内存极度低的情况下。
      一旦从OnReceive()方法中返回,这个BroadcastReceiver将不会再被激活,此时它的主进程就和任何其他运行于此应用程序中的组件拥有相同的优先级。这一点非常重要,如果进程仅仅只是拥有BroadReceiver(一个普遍的情况是用户从不或者是最近没有和它进行交互),因此一旦它从onReceive()方法中返回时,系统就会认为进程是空的并且主动的杀死它,以便这些资源可以被其他重要的进程利用。
      这意味着对于耗时的操作,可以采用将Service和BroadcastReceiver结合使用以确保执行这个操作的进程在整个执行过程中都保持激活状态。

文章转自: http://www.oschina.net/question/157182_45595

Android 四大组件之BroadcastReceiver相关推荐

  1. Android四大组件之BroadCastReceiver

    1. 基本概念 在Android 中,Broadcast 是一种广泛运用的在应用程序之间传输信息的机制.而BroadcastReceiver 是对发送出来的Broadcast 进行过滤接受并响应的一类 ...

  2. Android 四大组件丨BroadcastReceiver

    BroadcastReceiver 有几种形式及特点 BroadcastReceiver 可分为无序广播和有序广播 无序广播:通过sendBroadcast()方式发送,接收器接收顺序随机.特点是效率 ...

  3. Android四大组件之BroadcastReceiver详解

    1. 广播机制工作原理 ? 1.1 首先在需要发送信息的地方,把要发送的信息和用于过滤的信息(如Action.Category)装入一个Intent对象 1.2 然后通过调用 Context.send ...

  4. Android四大组件总结

    四大组件系列文章 Activity总结和补充:Activity总结和补充_fdsafwagdagadg6576的博客-CSDN博客 Android Binder&Aidl理解和补充:Andro ...

  5. Android四大组件---BroadcastReceiver

    前言: BroadcastReceiver(广播接收器),属于 Android 四大组件之一 在 Android 开发中,BroadcastReceiver 的应用场景非常多 今天,我将详细讲解关于B ...

  6. android 广播的权限,Android四大组件详解之BroadcastReceiver广播接收者

    Android四大组件详解---BroadcastReceicer广播接收者 广播有两个角色,一个是广播发送者,另一个是广播接收者. 广播按照类型分为两种,一种是全局广播,另一种是本地广播 全局广播: ...

  7. Android 四大组件之——Acitivity(一)

    一,什么是Activity activity是Android组件中最基本也是最为常见用的四大组件之一.Android四大组件有Activity,Service服务,Content Provider内容 ...

  8. android四大组件的作用简书,Android四大组件是什么

    Android四大组件是:活动.服务.广播接收器.内容提供商.它们的英文名称是ACTIVITY.SERVICE.BroadcastReceiver.Content Provider.四个组件分别起到不 ...

  9. android四大组件小整

    原文来自http://www.jianshu.com/p/478a34af17df 所谓的android四大组件一次是Activity.Service.BroadcastReceiver和Conten ...

最新文章

  1. python字符串的美化_Python构造自定义方法来美化字典结构输出
  2. java高并发(十三)并发容器J.U.C--AQS
  3. opencms的主工作区文件研究
  4. 【ArcGIS风暴】实验:公路建设成本的计算
  5. Acwing 1089. 烽火传递
  6. 三相阻容降压供电DCDC电源
  7. android设备如何苹果,Android安卓设备如何连接Mac的方法
  8. 获取矩阵元素的方法 4种方法 B(1,2) B(9) B(sub2ind(size(B),3,4))
  9. python读取文本数据--完善中
  10. vscode的code runner不生成临时文件
  11. CSDN 博客更换皮肤
  12. java属于什么语言_java语言属于什么语言?
  13. 5阶魔方阵c语言程序设计,五阶魔方阵源代码c语言课到程设计.docx
  14. 喜报丨酷雷曼成功挂牌北京股权交易中心科技创新板
  15. 本题要求实现一个函数,输出n行空心的数字金字塔。
  16. Python课程设计项目-基于机器学习的糖尿病风险预警分析系统
  17. scardsvr 智能卡修复工具原理及代码
  18. 智能风扇APP开发优点
  19. eclipse列名无效_sql 列名无效
  20. Slap the block

热门文章

  1. jira字段配置(域配置)_到期日、时间跟踪等根据需要自行配置
  2. PHP 简单案例[3]
  3. FusionCharts绘图插件详解
  4. python数字1 3怎么表示_Python3数据类型之数字
  5. 第9章 Quartz定时器和发送Email
  6. Dynamics 365 JS调WEB API 报missing privilege ae5c41f0-e823-4cb9-b25a-8ef020201973
  7. 看懂了再说自己是程序员哈哈
  8. Work_Day02(2019-10-24)_CFCA电子签章
  9. 通信行业基础知识大全
  10. 现代黄河三角洲的冲淤分区及地层特征