BroadcastReceiver概述

BroadcastReceiver,顾名思义就是“广播接收者”的意思,它是Android四大基本组件之一,这种组件本质上是一种全局的监听器,用于监听系统全局的广播消息。它可以接收来自系统和应用的的广播。广播之间信息的传递是通过Intent对象来传递的。

BroadcastReceiver是实现异步消息处理的组件。消息的实质就是Intent对象,因此可以通过附件携带消息。消息的来源有两个,一个是Android系统发出的系统事件消息,另一个是用户自定义的消息。消息的发送的模式有三种:正常有序持续(异步)。BroadcastReceiver必须先经过注册,才能够对消息进行处理。注册的方式有静态注册动态注册两种。对于有序消息,动态注册的BroadcastReceiver总是先于静态注册的BroadcastReceiver被触发。对于同样级别的动态注册的BroadcastReceiver,优先级别高的将先触发,而静态注册的BroadcastReceiver总是按照静态注册的顺序执行。

BroadcastReceiver的生命周期很短,BroadcastReceiver在onReceiver返回后声明周期即结束,因此对于需要长时间处理的任务,如果采用子线程来处理的话,有可能子线程还没有结束BroadcastReceiver就先结束了。一旦BroadcastReceiver结束,此时它所在的进程就很容易在系统需要内存时被优先杀死,那么正在工作的子线程也会被杀死。那就悲剧了。所以,对于需要长时间处理的任务,一般是调用其他的Service组件来执行,而不是新开启一个线程

BroadcastReceiver生命周期

BroadcastReceiver的生命周期比较简单,系统给予BroadcastReceiver的响应时间也才10s,当超出后,系统会直接报ANR(Application No Response)。每次广播到来时 , 会重新创建 BroadcastReceiver 对象 , 并且调用 onReceive() 方法 , 执行完以后 , 该对象即被销毁 . 当 onReceive() 方法在 10s 内没有执行完毕, Android 会认为该程序无响应 . 所以在BroadcastReceiver 里不能做一些比较耗时的操作 , 否侧会弹出 ANR 的对话框 。

BroadcastReceiver注册方式

静态注册就是在AndroidManifest.xml文件中定义,注册的广播接收器必须继承BroadReceiver。

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.bn.ex2_1">    <application android:icon="@drawable/icon" android:label="@string/app_name">        <activity android:name=".Sample2_1_Activity" android:label="@string/app_name">            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>        <!-- 注册自定义静态广播接收器 -->        <receiver android:name=".StaticReceiver">            <intent-filter>                <action android:name="com.bn.pp2.staticreceiver" />            </intent-filter>        </receiver>    </application></manifest>

动态注册就是在程序中使用Context.registerReceiver注册。
registerReceiver(BroadcastReceiver receiver, IntentFilter filter) ,第一个参数是我们要处理广播的 BroadcastReceiver (广播接收者,可以是系统的,也可以是自定义的);第二个参数是意图过滤器。

registerReceiver(receiver, filter, broadcastPermission, scheduler) ,第一个参数是 BroadcastReceiver (广播接收者,可以是系统的,也可以是自定义的);第二个参数是意图过滤器;第三个参数是广播权限;第四个参数是 Hander ;

注意:权限重复现象,如果功能清单文件里注册了权限,在该方法再注册,则 receiver 无法收到广播,如果功能清单文件里没有注册了权限,该方法注册也无法收到。当该方法没有注册权限,功能清单里注册的时候, receiver 能收到广播。

总结:在 Activity 中代码注册广播建议在: onResume() 中注册;

 IntentFilter dynamic_filter = new IntentFilter(); dynamic_filter.addAction(DYNAMICACTION);//添加动态广播的Action registerReceiver(dynamicReceiver, dynamic_filter);// 注册自定义动态广播消息

发送广播事件:通过Context.sendBroadcast来发送,由Intent来传递注册时用到的Action。

class DIYOnClickListener implements OnClickListener{//内部类OnClick监听器        public void onClick(View v) {            if(v.getId() == R.id.send_static){// 发送自定义静态注册广播消息                Intent intent = new Intent();                intent.setAction(STATICACTION);//设置Action                intent.putExtra("msg", "接收静态注册广播成功!");  //添加附加信息                sendBroadcast(intent);//发送Intent            }            else if(v.getId() == R.id.send_dynamic){// 发送自定义动态注册广播消息                Intent intent = new Intent();                intent.setAction(DYNAMICACTION);//设置Action                intent.putExtra("msg", "接收动态注册广播成功!");//添加附加信息                sendBroadcast(intent);//发送Intent    }}}

接收广播:当发送的广播被接收器监听到后,会调用onReceive()方法,并将包含消息的Intent对象传回。

public class StaticReceiver extends BroadcastReceiver {    @Override       //静态广播接收器执行的方法    public void onReceive(Context context, Intent intent) {        String msg = intent.getStringExtra("msg");        Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();}}
private BroadcastReceiver dynamicReceiver = new BroadcastReceiver() {//动态广播的Receiver        @Override        public void onReceive(Context context, Intent intent) {            //动作检测            if(intent.getAction().equals(DYNAMICACTION)){                 String msg = intent.getStringExtra("msg");                Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();             }        }};

BroadcastReceiver注销

动态注册的注销
动态注册的BroadcastReceiver在使用的时候,在Activity进入停止或者销毁状态的时候使用unregisterReceiver方法将注册的BroadcastReceiver注销掉。在 Activity 中代码注销广播建议在onPuase() 中注销。

// 代码中注销广播unregisterReceiver(mInfoReceiver);

静态注册的注销
当使用静态注册的BroadcastReceiver进行注销,根据官方API的说明:If this BroadcastReceiver was launched through a tag, then the object is no longer alive after returning from this function. This means you should not perform any operations that return a result to you asynchronously. (如果通过标签来注册的BroadcastReceiver,那么该对象的实例在onReceive被调用之后就会在任意时间内被销毁。)从而得出我们并不需要担心静态注册的BroadcastReceiver的销毁问题。

系统广播消息

系统广播被Android用来通知各应用组件一些重要的系统事件,被定义为android.content.intent中的Action常量:(注,默认的常量名前均为android.intent.action.XXXXX;有加前缀的分别为android.intent.category.BROWSABLE; android.server.checkin.XXXX。为了方便,统一到了一起,造成的不严谨,深表抱歉,但有好处。)

<receiver android:name=".MyReceiver">    <intent-filter>        <action android:name="android.intent.action.MY_BROADCAST"/>        <category android:name="android.intent.category.DEFAULT" />    </intent-filter></receiver>
Action常量名称 系统实践描述
ADD_SHORTCUT 在系统中添加一个快捷方式
ALL_APPS 列举所有可用的应用
ANSWER 处理拨入的电话
BATTERY_CHANGED 充电状态,或者电池的电量发生变化
BOOT_COMPLETED 在系统启动后。 这个动作被广播一次(只有一次)
category.BROWSABLE 能够被浏览器安全使用的 activities 必须支持这个类别
BUG_REPORT 显示 activity 报告错误
CALL 拨打电话。被呼叫的联系人在数据中指定
CFF 语音电话的呼叫转移状态已经改变
CLEAR_CREDENTIALS 清除登陆凭证
CONFIGURATION_CHANGED 设备的配置信息已经改变,参见 Resources.Configuration
DATA_ACTIVITY 电话的数据活动(data activity)状态(即收发数据的状态)已经改变
DATA_STATE 电话的数据连接状态已经改变
DATE_CHANGED 日期被改变
VIEW 和 VIEW_ACTION 相同,是在数据上执行的标准动作
DELETE 从容器中删除给定的数据
DIAL 拨打数据中指定的电话号码
EDIT 为制定的数据显示可编辑界面
EMERGENCY_DIAL 拨打紧急电话号码
server.checkin.FOTA_CANCEL 取消所有被挂起的更新下载
server.checkin.FOTA_INSTALL 更新已经被确认,马上就要开始安装
server.checkin.FOTA_READY 更新已经被下载。可以开始安装
server.checkin.FOTA_RESTART 恢复已经停止的更新下载
server.checkin.FOTA_UPDATE 通过 OTA 下载并安装操作系统更新
GET_CONTENT 让用户选择数据并返回
INSERT 在容器中插入一个空项 (item)
LOGIN 获取登录凭证
MAIN 作为主入口点启动,不需要数据
MEDIABUTTON 用户按下了“Media Button”
MEDIA_BAD_REMOVAL 扩展介质已经从 SD 卡插槽拔出,但是挂载点 还没解除
MEDIA_EJECT 用户想要移除扩展介质(拔掉扩展卡)
MEDIA_MOUNTED 扩展介质被插入,而且已经被挂载
MEDIA_REMOVED 扩展介质被移除
MEDIA_SCANNER_FINISHED 已经扫描完介质的一个目录
MEDIA_SCANNER_STARTED 开始扫描介质的一个目录
MEDIA_SHARED 扩展介质的挂载被解除 。因为它已经作为 USB 大容量存储被共享
MEDIA_UNMOUNTED 扩展介质存在,但是还没有被挂载
MWI 电话的消息等待(语音邮件)状态已经改变
PACKAGE_ADDED 设备上新安装了一个应用程序包
PACKAGE_REMOVED 设备上删除了一个应用程序包
PHONE_STATE 电话状态已经改变
PICK 从数据中选择一个项目 ,将被选中的项目返回
PICK_ACTIVITY 选择一个 activity,返回被选择的 activity 的类(名)
PROVIDER_CHANGED 更新将要(真正)被安装
PROVISIONING_CHECK 要求 polling of provisioning service 下载最新的设置
RUN 行数据(指定的应用),无论它(应用)是什么
SCREEN_OFF 屏幕被关闭
SCREEN_ON 屏幕已经被打开
SENDTO 向 data 指定的接收者发送一个消息
SERVICE_STATE 电话服务的状态已经改变
SETTINGS 显示系统设置
SIG_STR 电话的信号强度已经改变
STATISTICS_REPORT 要求 receivers 报告自己的统计信息
STATISTICS_STATE_CHANGED 统计信息服务的状态已经改变
SYNC 执行数据同步
TIMEZONE_CHANGED 时区已经改变
TIME_SET 时间已经改变(重新设置)
TIME_TICK 当前时间已经变化(正常的时间流逝)
UMS_CONNECTED 设备进入 USB 大容量存储模式
UMS_DISCONNECTED 设备从 USB 大容量存储模式退出
VIEW_ACTION 向用户显示数据
WALLPAPER_CHANGED 系统的墙纸已经改变
WALLPAPER_SETTINGS 显示选择墙纸的设置界面
WEB_SEARCH 执行 web 搜索
XMPP_CONNECTED XMPP 连接已经被建立
XMPP_DI XMPP 连接已经被断开

参考
版权申明:本文参考内容版权归原作者所有,感谢原作者的共享。
http://my.oschina.net/zhongwenhao/blog/143156
http://yangguangfu.iteye.com/blog/1063732

更多相关文章

  1. Android常见的Event-driven方案
  2. Android(安卓)API demos 阅读笔记 5
  3. Android应用程序线程的消息循环模型
  4. Android基于MQTT实现发布消息与监听topic接收消息
  5. Android实时监听网络状态
  6. 十、Android的消息机制
  7. Android中的消息通知(NotificationManager和Notification)
  8. 【Android】Handler、Looper源码分析
  9. Android之handler篇

随机推荐

  1. android textview 如何实现像新浪微博@用
  2. Android(安卓)显示系统 --- Surface Flin
  3. Android浏览页面时报数据连接性问题
  4. Android(安卓)应用反编译方法
  5. Android(安卓)浏览器设置中的搜索引擎
  6. Android(安卓)中WebView中video视频自动
  7. Android(安卓)实现发送彩信方法 (MMS),非
  8. Android(安卓)如何预置APK M
  9. 自定义EditText
  10. Android(安卓)init.rc执行顺序