广播机制介绍
每个应用程序都可以对自己感兴趣的广播注册,这些广播有可能是来自于系统,也有可能是来自于其他应用程序。
广播主要分为两种类型:
1.标准广播:完全异步执行的广播,这种广播效率比较高但是无法被截断。
2.有序广播:在广播发出之后,同一时刻只有一个广播接收器能够接收到这条广播消息,广播接收器中的逻辑执行完毕后,广播才会继续传递。
接收系统广播
动态注册
动态注册是在代码中注册。
注册监听的方式:
public class MainActivity extends AppCompatActivity{
//网络变化的接收器
private NetworkChangeReceiver networkReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
//...
IntentFilter filter = new IntentFilter();
//添加需要监听的事件
filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
//注册广播
registerReceiver(networkReceiver, filter);
}
@Override
protected void onDestroy() {
//...
//页面销毁时一定要取消注册广播,否则会导致内存泄漏
unregisterReceiver(networkReceiver);
}
}
class NetworkChangeReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context,Intent intent){
//接收到广播后执行的操作
}
}
静态注册
静态注册是在AndroidManifest.xml文件中注册。
动态注册必须要在程序启动后才可以接收到广播,静态注册可以在程序未启动的情况下接收到广播
class BootCompleteReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context,Intent intent){
//接收到广播后执行的操作
}
}
<receiver
android:name=".BootBroadcastReceiver"
android:exported="true"
android:enabled="true">
<intent-filter android:priority="100">
<action android:name="android.net.wifi.RSSI_CHANGED" />
<action android:name="android.net.wifi.STATE_CHANGE" />
<action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
</intent-filter>
</receiver>
exported是否允许这个广播接收器接收本程序以外的广播
enabled是否启用这个广播接收器
priority广播优先级
action需要监听的事件
-
onReceive()方法里面不能添加过多的逻辑或者进行耗时操作,因为广播接收器不允许开启线程,如果onReceive()运行了较长时间没有结束,程序会报错。
发送自定义广播
发送标准广播
自定义一个广播接收器(这里采用静态注册)
<receiver
android:name=".MyBroadcastReceiver"
android:exported="true"
android:enabled="true">
<intent-filter android:priority="100">
<action android:name="com.example.broadcasttest.MY_BROADCAST" />
</intent-filter>
</receiver>
class MyBroadcastReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context,Intent intent){
//接收到广播后执行的操作
}
}
比如在MainActivity里面实现发送广播
public class MainActivity extends AppCompatActivity{
@Override
protected void onCreate(Bundle savedInstanceState) {
//...
//发送自定义广播
Intent intent=new Intent("com.example.broadcasttest.MY_BROADCAST");
sendBroadcast(intent);
}
}
发送有序广播
广播是一种跨进程的通信方式,应用程序A发出的广播,其他应用程序也可以接收到。
在应用程序A中自定义广播接收器MyBroadcastReceiver,优先级设置为100
<receiver
android:name=".MyBroadcastReceiver"
android:exported="true"
android:enabled="true">
<intent-filter android:priority="100">
<action android:name="com.example.broadcasttest.MY_BROADCAST" />
</intent-filter>
</receiver>
class MyBroadcastReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context,Intent intent){
//接收到广播后执行的操作
//abortBroadcast(); 可以截断后续传递
}
}
在应用程序B中定义广播接收器AnotherBroadcastReceiver
<receiver
android:name=".AnotherBroadcastReceiver"
android:exported="true"
android:enabled="true">
<intent-filter android:priority="99">
<action android:name="com.example.broadcasttest.MY_BROADCAST" />
</intent-filter>
</receiver>
class AnotherBroadcastReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context,Intent intent){
//接收到广播后执行的操作
}
}
两个接收器都监听"com.example.broadcasttest.MY_BROADCAST"广播
在MainActivity中发送广播
public class MainActivity extends AppCompatActivity{
@Override
protected void onCreate(Bundle savedInstanceState) {
//...
//发送自定义广播
Intent intent=new Intent("com.example.broadcasttest.MY_BROADCAST");
//第二个参数与权限相关,这里设置为null
sendOrderedBroadcast(intent,null);
}
}
因为应用程序A接收器优先级为100,所以MyBroadcastReceiver先收到广播,在onReceive()中进行处理,执行完毕后再调用AnotherBroadcastReceiver的onReceive()。如果想要截断,不继续向下传递的话可以在代码里加入abortBroadcast()。
本地广播
上述广播是系统全局广播,发出的广播可以被任何应用程序接收到,容易引起安全问题。所以Android引入了一套本地广播机制,通过LocalBroadcastManager实现。
在发送广播的时候
public class MainActivity extends AppCompatActivity{
private LocalBroadcastManager localBroadcastManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
//...
localBroadcastManager=LocalBroadcastManager.getInstance(this);
Intent intent=new Intent("com.example.broadcasttest.LOCAL_BROADCAST");
localBroadcastManager.sendBroadcast(intent);
}
}
注册监听的时候其余与上述注册监听过程一致,只不过是调用localBroadcastManager.registerReceiver方法
localBroadcastManager.registerReceiver(receiver,intentFilter);
localBroadcastManager.unregisterReceiver(receiver);