BoardcastReceiver是Android四大组件之一,本质上是一个全局的监听器,可以用于组件之间的通信等场景。
创建一个广播接收器继承于BroadcastReceiver,并重写其**onReceive()**方法。当广播接收器接收到相应的广播,将回调onReceive方法。注意,一般情况下,BroadcastReceiver运行在UI线程,不能进行耗时操作
public class MyBroadcastReceiver extends BroadcastReceiver {
//接收到广播后自动调用该方法
@Override
public void onReceive(Context context, Intent intent) {
//收到广播后的一些处理
}
}
注册方式有两种——静态注册与动态注册
静态注册就是指在AndroidManifest.xml 中,通过标签来声明,如:
用于接收网络状态改变时发出的广播
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
intent-filter>
receiver>
静态注册的标签说明
android:exported=["true" | "false"]
android:icon="drawable resource"
android:label="string resource"
android:name=".MyBroadcastReceiver"
android:permission="string"
android:process="string" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
intent-filter>
receiver>
在代码中通过调用Context的**registerReceiver()**方法即可动态注册BroadcastReceiver
动态广播最好在Activity的onResume(*)中注册,在onPause()中注销
//实例化BroadcastReceiver子类 & IntentFilter
mBroadcastReceiver mBroadcastReceiver = new mBroadcastReceiver();
IntentFilter intentFilter = new IntentFilter();
//设置接收广播的类型
intentFilter.addAction(android.net.conn.CONNECTIVITY_CHANGE);
//调用Context的registerReceiver()方法进行动态注册
registerReceiver(mBroadcastReceiver, intentFilter);
注册广播后,不要忘记在onDestroy之类的地方销毁广播
//销毁在onCreate()方法中的广播
unregisterReceiver(mBroadcastReceiver);
Q:为何不在onCreate() & onDestory() 或 onStart() & onStop()中注册、注销呢?
A:这涉及到Activity的生命周期。当系统因内存不足要回收Activity占用的资源时,Activity在执行完onPause()方法后就会被销毁,有些生命周期方法onStop(),onDestory()就不会执行。当再回到此Activity时,是从onCreate方法开始执行。假设我们将广播的注销放在onStop(),onDestory()方法里的话,有可能在Activity被销毁后还未执行onStop(),onDestory()方法,即广播仍还未注销,从而导致内存泄露。但是,onPause()一定会被执行,从而保证了广播在App死亡前一定会被注销,从而防止内存泄露。
广播的类型主要分为5类:
普通广播,即开发者自己定义的广播,发送方式如下:
Intent intent = new Intent();
//对应BroadcastReceiver中intentFilter的action
intent.setAction(BROADCAST_ACTION);
//发送广播
sendBroadcast(intent);
如果注册了的广播接收者中IntentFilter的action与上述匹配,则会接收此广播(回调onReceive())。如下MyBroadcastReceiver则会接收上述广播。
<receiver
<intent-filter>
<action android:name="BROADCAST_ACTION" />
intent-filter>
receiver>
若发送广播有相应权限,那么广播接收者也需要相应权限
Android中内置了多个系统广播:只要涉及到手机的基本操作(如开机、网络状态变化、拍照等等),都会发出相应的广播。每个广播都有特定的Intent - Filter(包括具体的action),Android系统广播action如下:
系统操作 | action |
---|---|
关闭或打开飞行模式 | Intent.ACTION_AIRPLANE_MODE_CHANGED |
充电时或电量发生变化 | Intent.ACTION_BATTERY_CHANGED |
电池电量低 | Intent.ACTION_BATTERY_LOW |
电池电量充足(即从电量低变化到饱满时会发出广播 | Intent.ACTION_BATTERY_OKAY |
系统启动完成后(仅广播一次) | Intent.ACTION_BOOT_COMPLETED |
检测网络变化 | ConnectivityManager.CONNECTIVITY_ACTION |
按下照相时的拍照按键(硬件按键)时 | Intent.ACTION_CAMERA_BUTTON |
屏幕锁屏 | Intent.ACTION_CLOSE_SYSTEM_DIALOGS |
设备当前设置被改变时(界面语言、设备方向等) | Intent.ACTION_CONFIGURATION_CHANGED |
插入耳机时 | Intent.ACTION_HEADSET_PLUG |
未正确移除SD卡但已取出来时(正确移除方法:设置–SD卡和设备内存–卸载SD卡) | Intent.ACTION_MEDIA_BAD_REMOVAL |
插入外部储存装置(如SD卡) | Intent.ACTION_MEDIA_CHECKING |
成功安装APK | Intent.ACTION_PACKAGE_ADDED |
成功删除APK | Intent.ACTION_PACKAGE_REMOVED |
重启设备 | Intent.ACTION_REBOOT |
屏幕被关闭 | Intent.ACTION_SCREEN_OFF |
屏幕被打开 | Intent.ACTION_SCREEN_ON |
关闭系统时 | Intent.ACTION_SHUTDOWN |
重启设备 | Intent.ACTION_REBOOT |
当使用系统广播时,只需要在注册广播接收者时定义相关的action即可,并不需要手动发送广播,当系统有相关操作时会自动进行系统广播 。
有序广播指的是发送出去的广播被广播接收者按照先后顺序接收的广播。
**广播接受者接收广播的顺序规则(同时面向静态和动态注册的广播接受者) **
有序广播的特点
有序广播的使用
有序广播的使用过程与普通广播非常类似,差异仅在于广播的发送方式:
sendOrderedBroadcast(intent);
由于粘性广播在API 21中已经失效,所以没有考虑了解
由于Android中的广播可以跨App直接通信(exported对于有intent-filter情况下默认值为true),可能出现一些问题,比如:
因此,出现了App应用内广播这一形式的广播。可理解为一种局部广播,广播的发送者和接收者都同属于一个App。它相对全局广播的优势在于:安全性高,效率高 。
应用内广播的使用
方法1:将全局广播设置成局部广播
方法2:使用封装好的LocalBroadcastManager类
其使用方式上与全局广播几乎相同,只是注册/取消注册广播接收器和发送广播时将参数的context变成了LocalBroadcastManager的单一实例
**注:对于LocalBroadcastManager方式发送的应用内广播,只能通过LocalBroadcastManager动态注册,不能静态注册 **
//注册应用内广播接收器
//步骤1:实例化BroadcastReceiver子类 与 IntentFilter mBroadcastReceiver
mBroadcastReceiver = new MyBroadcastReceiver();
IntentFilter intentFilter = new IntentFilter();
//步骤2:实例化LocalBroadcastManager的实例
localBroadcastManager = LocalBroadcastManager.getInstance(this);
//步骤3:设置接收广播的类型
intentFilter.addAction(android.net.conn.CONNECTIVITY_CHANGE);
//步骤4:调用LocalBroadcastManager单一实例的registerReceiver()方法进行动态注册
localBroadcastManager.registerReceiver(mBroadcastReceiver, intentFilter);
//取消注册应用内广播接收器
localBroadcastManager.unregisterReceiver(mBroadcastReceiver);
//发送应用内广播
Intent intent = new Intent();
intent.setAction(BROADCAST_ACTION);
localBroadcastManager.sendBroadcast(intent);
对于不同注册方式的广播接收器回调OnReceive(Context context,Intent intent)中的context返回值是不一样的:
广告时间
我是N0tExpectErr0r,一名广东工业大学的大二学生
欢迎来到我的个人博客,所有文章均在个人博客中同步更新哦
http://blog.N0tExpectErr0r.cn