目录
1.广播介绍
广播,android四大组件之一。Android提供了一套完整的API,允许应用程序自由地发送和接受广播。发送广播使用Intent,接受广播使用Broadcast Receiver(广播接收器)。
广播可用于不同app之间的组件之间消息通信,同一app具有多个进程的不同组件之间的消息通信,特定情况下与系统通信,例如检测网络情况。
android中的广播使用了设计模式中的观察者模式:基于消息的发布/订阅事件模型。模型有3个角色:①消息订阅者(广播接受者),②消息发布者(广播发送者),③消息中心(AMS,Activity Manager Service)。
2.广播分类
按照广播的类型,可分为标准广播,有序广播,粘性广播。
①标准广播:一种完全异步执行的广播,发送后所有广播接收器几乎在同一时间接受到这条广播。
②有序广播:一种同步执行的广播,发送后同一时间只有一个广播接收器收到这条广播,前面接收器执行完相应逻辑后广播才 能继续传递。优先级高的接收器先接收,并且可以截断广播,这样后面的接收器就接收不到被截断的广播。(优先级相同的接 收器动态注册的优先)
③粘性广播:是指广播接收器一注册马上就能接收到广播的一种机制,当然首先系统要存在广播。而普通广播就是要先注册 广播接收器,然后广播被发送到系统,广播接收器才能接收到广播。(使用较少,5.0后API失效)
按照广播的传播范围,可分为系统广播和本地广播:
①系统广播:这种广播可以被任何其他应用程序接收到。
②本地广播:只能在应用程序的1内部进行传递。(无法通过静态注册方式接收)
3.广播基本使用
广播的发送通过Intent完成,接收需要使用广播接收器。广播接收器可以对感兴趣的广播进行注册,当相应的广播发送时,广播接收器就能接收到该广播,并执行相应的逻辑。注册的方式有两种:动态注册,静态注册。动态注册是指在代码中进行注册,静态注册是指在AndroidManifest.xml中注册。
首先先创建广播接收器,创建一个类,继承BroadcastReceiver,重写onReceive()即可。这样当接收到广播时,onReceive()就会调用执行相应逻辑。在onReceive()中不要进行耗时操作,否则将导致ANR。
public class MBroadcastReceiver extends BroadcastReceiver{
//重写方法
@Override
public void onReceive(Context context, Intent intent) {
}
}
然后为接收器注册感兴趣的广播。静态注册(接收开机广播需添加对应的权限):
<receiver android:name=".FirstActivity$MBroadcastReceiver"
android:enabled="true" //是否启用
android:exported="true"> //是否接收应用外广播
<intent-filter> //添加想接收广播的action
<action android:name="android.intent.action.BOOT_COMPLETED"/> //开机广播
</intent-filter>
</receiver>
动态注册:
MBroadcastReceiver receiver = new MBroadcastReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("android.net.conn.CONNECTIVITY_CHANGE");//添加action
registerReceiver(receiver,filter);
动态注册的都要取消注册才行,否则会导致内存泄漏,(不可重复注册,注销)一般在onPause()中调用unregisterReceiver()方法。
unregisterReceiver(receiver);
两种方式对比:
无论是动态还是静态,只要给接收器添加对应的action,就能接收到对应的广播。发送时通过设置Intent的action,即可将广播发送到对应的接收器。
Intent intent = new Intent("com.example.broadcast.MY_BROADCAST");
sendBroadcast(intent); //发送普通广播
sendOrderedBroadcast(intent,null); //发送有序广播(第二个参数是与权限相关的字符串)
接收器的优先级同样有两种指定方式,第一种是在代码中,第二种在AndroidManifest.xml中。
MBroadcastReceiver receiver = new MBroadcastReceiver();
IntentFilter filter = new IntentFilter();
filter.setPriority(10); //设置优先级
registerReceiver(receiver,filter);
<receiver android:name=".FirstActivity$MBroadcastReceiver"
android:enabled="true"
android:exported="true">
<intent-filter android:priority="10"> //设置优先级
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
优先级高的接收器能够截断广播,使优先级低的接收不到。通过调用abortBroadcast()方法。
public class MBroadcastReceiver extends BroadcastReceiver{
//重写方法
@Override
public void onReceive(Context context, Intent intent) {
abortBroadcast(); //截断广播
}
}
上面的发送和接收的都是系统广播,下面介绍本地广播。本地广播用法也不复杂,主要使用一个LocalBroadcastManager来对广播进行管理,并提供发送广播和注册广播接收器的方法。
public class FirstActivity extends AppCompatActivity {
private MBroadcastReceiver receiver; //广播接收器
private LocalBroadcastManager manager; //本地广播管理器
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_first);
receiver = new MBroadcastReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("com.example.broadcast.MY_BROADCAST"); //设置action
manager = LocalBroadcastManager.getInstance(this);
manager.registerReceiver(receiver,filter); //注册
Button button = findViewById(R.id.bt_change);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("com.example.broadcast.MY_BROADCAST");
manager.sendBroadcast(intent); //发送本地广播
}
});
}
@Override
protected void onPause() {
super.onPause();
manager.unregisterReceiver(receiver); //取消注册
}
public class MBroadcastReceiver extends BroadcastReceiver{
//重写方法
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"Received",Toast.LENGTH_SHORT).show();
}
}
}
上面是较为完整发送本地广播的代码,与发送系统广播十分相似。注意,本地广播只能动态注册,因为静态注册是主要是为了在应用程序未启动时也能接收到广播,而本地广播只在应用程序内传播,发送时应用一定启动了,所以不需要静态注册。另外,本地广播更加安全高效。