广播的相关知识
原理:
从实现原理看上,Android中的广播使用了观察者模式,基于消息的发布/订阅事件模型。因此,从实现的角度来看,Android中的广播将广播的发送者和接受者极大程度上解耦,使得系统能够方便集成,更易扩展。具体实现流程要点粗略概括如下:
1.广播接收者BroadcastReceiver通过Binder机制向AMS(Activity Manager Service)进行注册;
2.广播发送者通过binder机制向AMS发送广播;
3.AMS查找符合相应条件(IntentFilter/Permission等)的BroadcastReceiver,将广播发送到BroadcastReceiver(一般情况下是Activity)相应的消息循环队列中;
4.消息循环执行拿到此广播,回调BroadcastReceiver中的onReceive()方法。
对于不同的广播类型,以及不同的BroadcastReceiver注册方式,具体实现上会有不同。但总体流程大致如上。
由此看来,广播发送者和广播接收者分别属于观察者模式中的消息发布和订阅两端,AMS属于中间的处理中心。广播发送者和广播接收者的执行是异步的,发出去的广播不会关心有无接收者接收,也不确定接收者到底是何时才能接收到。
2.自定义广播接收者
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//接受到广播后,执行下面的逻辑
}
}
清单文件:
<receiver
//此广播接收者类是MyReceiver
android:name=".MyReceiver" >
//用于接收网络状态改变时发出的广播
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
当网络发生变化时,就会回掉到广播接收者的onReceive()中
3. 动态注册
@Override
protected void onResume(){
super.onResume();
// 1. 实例化BroadcastReceiver子类 & IntentFilter
MyBroadcastReceiver mBroadcastReceiver = new MyBroadcastReceiver();
IntentFilter intentFilter = new IntentFilter();
// 2. 设置接收广播的类型
intentFilter.addAction(android.net.conn.CONNECTIVITY_CHANGE);
// 3. 动态注册:调用Context的registerReceiver()方法
registerReceiver(mBroadcastReceiver, intentFilter);
}
// 注册广播后,要在相应位置记得销毁广播
// 即在onPause() 中unregisterReceiver(mBroadcastReceiver)
// 当此Activity实例化时,会动态将MyBroadcastReceiver注册到系统中
// 当此Activity销毁时,动态注册的MyBroadcastReceiver将不再接收到相应的广播。
@Override
protected void onPause() {
super.onPause();
//销毁在onResume()方法中的广播
unregisterReceiver(mBroadcastReceiver);
}
}
4. 发送广播
广播的类型主要分为5类:
- 普通广播(
Normal Broadcast
) :就是我们自定义的广播 - 系统广播(
System Broadcast
) :想系统的开机,发送sms等广播 - 有序广播(
Ordered Broadcast
) :发送出去的广播被广播接收者按照先后顺序接收,可以在清单文件里配置优先级,最大1000,最小-1000
4.1发送无序广播
Intent intent = new Intent();
intent.setAction("包名+功能");
sendBoardcarst(intent);
定义一个广播,清单里面的action就是set的Action
这也是一种无序广播,效果高,但是不能修改广播的内容,和拦截广播
4.2 发送有序广播
Intent intent = new Intent();
intent.setAction("包名+功能");
sendOrderBoardcarst(intent,null,null,null,1,“内容”,null);
可以定义很多广播,每个广播可以设置优先级,最大是1000,最小是-1000,意图都是action
有序广播,可以通过在onRevice()中的getResultData()获取广播的内容,
可以通过setResultData("xxx")修改广播的内容
可以通过aboutRevice()去拦截广播(这些在无序中是不可以的)
动态注册和静态注册区别?
动态注册是在Java类中注册,而静态注册实在AndroidManifest.xml中注册。
动态注册的广播接收器不是常驻型的,会随着所注册的Activity的结束而结束,如果所在的Activity已经destroy了,那么该广播接收器也就不能再继续接收广播了。注意:在Activity结束前,要取消注册广播接收器,不然会导致内存泄露;静态注册的广播接收器是常驻型的,即使所在的APP被关闭了,也是可以接收到广播的。
注意:
当广播为标准广播时:
无视优先级,动态注册的优先于静态注册的
同优先级的同类广播接收器,动态注册:先注册的优先于后注册的;静态注册:先扫描的优先于后扫描的
当广播为有序广播时:
优先级高的先接收
同优先级的广播接收器,动态注册的优先于静态注册的
同优先级的同类广播接收器,动态注册:先注册的优先于后注册的;静态注册:先扫描的优先于后扫描的