概念:
原理:
具体使用:
1.动态注册
1.通过继承BroadcastReceiver建立动态广播接收器或者匿名内部类实现
2.实例化IntentFilter对象
3.注册广播接收
4.移除广播接收器优化内存空间避免内存溢出
BroadcastReceiver mBroadcasrReceive = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(action.equals(Constant.LOGIN_SUCCESS)){
text_send.setText("收到动态广播");
}
}
};
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Constant.LOGIN_SUCCESS);
registerReceiver(mBroadcasrReceive,intentFilter);
@Override
protected void onPause(){
super.onPause();
unregisterReceiver(mBroadcasrReceive);
}
发送广播:
Intent mintent = new Intent(Constant.LOGIN_SUCCESS);
mintent.putExtra("yanner","发送广播");
//发送广播
sendBroadcast(mintent);
这样动态方式就可以实现。注意:动态广播最好在Activity的onResume()注册,onPause()注销。动态广播,有注册就必然有注销,否则会导致内存泄漏,重复注册和注销都是不允许的。为什么要在onPause()注销呢,因为onPause()在App死亡前一定会被执行,这样保证广播在App死亡前一定会被注销,从而防止内存泄漏。不在onStop()&onDestory()注销因为当系统如果内存不足时要回收Activity占用的资源时,Activity在执行完onPause()方法后就会被销毁,有些生命周期方法onStop(),onDestory()就不会执行。当再回到此Activity时,是从onCreate方法开始执行。所以如果将广播的注销放在onStop(),onDestory()方法里的话,有可能在Activity被销毁后还未执行onStop(),onDestory()方法,广播仍未注销,从而导致内存泄漏。,但是onPause()一定会被执行的。
2.静态注册
1.继承BroadcastReceiver,重写onReceive方法
public class StaticReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(Constant.REGISTER_SUCCESS)){
Toast.makeText(context,"收到静态广播",Toast.LENGTH_SHORT).show();
}
}
}
2.在清单文件注册
<!--继承BroadcastReceiver子类的类名-->
<receiver android:name=".receiver.StaticReceiver">
<intent-filter>
<!--action android:name="com.broadcast.REGISTER_SUCCESS"必须跟发送广播的action一致 -->
<action android:name="com.broadcast.REGISTER_SUCCESS"/>
</intent-filter>
</receiver>
注意这是自定义广播。
也可以使用系统广播:
以接收短信为例:
public class MyBroadcastReceiver extends BroadcastReceiver {
//action 名称
String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
@Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(SMS_RECEIVED)){
//相关处理
}
}
}
在AndroidManifest.xml中注册
<receiver android:name=".receiver.MyBroadcastReceiver">
<!-- 接收短信-->
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</receiver>
注意还得要添加权限:
<!--//权限 --> <uses-permission android:name = "android.permission.RECEIVE_SMS" />
两种方式对比
注册方式 | 特点 | 使用场景 |
---|---|---|
静态注册 | 常驻,不受任何组件的生命周期影响,应用程序关闭后,如果有信息广播里,程序依然会被系统调用,但是耗电站内存 | 需要时刻监听广播 |
动态注册 | 不是常驻,灵活,跟随组件的生命周期变化,组件结束 == 广播结束,在组件结束是,必须移除广播接收器 | 需要特定时刻监听广播 |
广播类型及广播的收发
public class FirstReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String msg = intent.getStringExtra("msg");
Log.d("MyFirstReceiver", msg);
//将数据传输给下一个广播接收者
setResultData("This is the Second Msg From MyFirstReceiver");
}
}
public class SecondReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//获得上一个广播接收者传过来的数据
String msg = getResultData();
Log.d("MyThirdReceiver", msg);
}
}
2.在AndroidManifest.xml中注册三个广播接收者
<receiver android:name=".receiver.FirstReceiver">
<intent-filter android:priority="100">
<action android:name="OrderBroadcast"/>
</intent-filter>
</receiver>
<receiver android:name=".receiver.SecondReceiver">
<intent-filter android:priority="20">
<action android:name="OrderBroadcast"/>
</intent-filter>
</receiver>
3.发送广播:
Intent mintent = new Intent("OrderBroadcast");
mintent.putExtra("yanner","发送广播");
//发送广播
// sendBroadcast(mintent);
sendOrderedBroadcast(mintent,null);
打印log:
11-15 20:48:49.283 32069-32069/com.example.administrator.broadcastdemo D/11111: This is the First Msg From MyFirstReceiver
11-15 20:48:49.302 32069-32069/com.example.administrator.broadcastdemo D/1111: This is the Second Msg From MyFirstReceiver
每个接收者都加了一个属性:priority,这个属性表示有序广播中的优先级,值越高表示优先级越高,当广播发出时,优先级最高的便会第一个接收到广播并拦截下来,然后继续往优先级低的传递下去。
总结:
广播接收者接收广播的顺序规则是:
按照priority属性值从大到小排序
priority属性一样时,动态注册广播优先
先接收的广播可以对广播进行拦截,后面接收的广播接收者不再接收到此广播
先接收的广播接收者可以对广播进行修改,后接收的广播接收者将接收到被修改后的广播
终止广播的方法是:abortBroadcast();