您的位置:首页 > 移动开发 > Android开发

Android温故之-BroadcastReceiver

2016-04-13 22:37 651 查看

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_CONNECTEDXMPP 连接已经被建立
XMPP_DIXMPP 连接已经被断开
参考

版权申明:本文参考内容版权归原作者所有,感谢原作者的共享。

/article/3544257.html

/article/3744693.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: