前面我们学习了Android的标准广播(Normal broadcasts)发送,本章我们来学习Android的另一种广播发送方式——有序广播(Ordered broadcast)。
定义
有序广播(Ordered broadcast)是一种同步执行的广播,在广播发出后,同一时刻只能有一个广播接收器能够接收到这条广播消息,当这个广播接收器中的逻辑执行完毕后,广播消息才会继续传递。所以此时的广播接收器是有顺序的,优先级高的广播接收器优先接收到广播消息,并且可以截断正在传递的广播,使后面的广播接收器无法收到广播消息。
工作流程示意图
img_1.png案例:
在发送广播之前,我们需要定义一个广播接收器(Broadcast Receiver)来接收广播。在这里我们分别创建两个继承于BroadcastReceiver的类MyBroadcastReceiver、MyBroadcastReceiverTwo。在onReceive()处理你接收到的广播内容,在这里我用logd分别打印一下输出的接收器名称,以便观察哪个接收器优先执行。
//接收器1
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// TODO: This method is called when the BroadcastReceiver is receiving
// an Intent broadcast.
Log.d("Broadcast received", "onReceive:MyBroadcastReceiver");
}
}
//接收器2
public class MyBroadcastReceiverTwo extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// TODO: This method is called when the BroadcastReceiver is receiving
// an Intent broadcast.
Log.d("Broadcast received", "onReceive:MyBroadcastReceiverTwo");
}
}
我们知道,Android广播接收器有两种注册方式。我们可以用以下任意一种来进行注册。
静态注册
在AndroidManifest.xml文件了,我们可以看到多了两个<receiver>标签,这是因为在创建MyBroadcastReceiver 和MyBroadcastReceiver Two接收器时,系统自动帮我们补全了。分别在两个<receiver>标签里添加<intent-filter></intent-filter>代码
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
...>
<application ...>
<receiver
android:name=".MyBroadcastReceiverTwo"
android:enabled="true"
android:exported="true">
<intent-filter android:priority="100">
<action android:name="broadcast" />
</intent-filter>
</receiver>
<receiver
android:name=".MyBroadcastReceiver"
android:enabled="true"
android:exported="true">
<intent-filter android:priority="200">
<action android:name="broadcast" />
</intent-filter>
</receiver>
<activity android:name=".MainActivity">
...
</activity>
</application>
</manifest>
我们可以发现,和标准广播的静态注册相比,intent-filter标签里多了个priority属性。priority属性表示优先级,数值越高表示优先级越高。broadcast为自定义的广播名称。
动态注册
在需要接收界面进行注册,代码如下
public class MainActivity extends AppCompatActivity {
MyBroadcastReceiver receiver;
MyBroadcastReceiverTwo receiver2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//接收器1
receiver = new MyBroadcastReceiver();
IntentFilter intentFilter1 = new IntentFilter("broadcast");
intentFilter1.setPriority(200);
registerReceiver(receiver,intentFilter1);
//接收器2
receiver2 = new MyBroadcastReceiverTwo();
IntentFilter intentFilter2 = new IntentFilter("broadcast");
intentFilter2.setPriority(100);
registerReceiver(receiver2,intentFilter2);
//Send broadcast
Button button = findViewById(R.id.send_button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setAction("broadcast");
sendOrderedBroadcast(intent,null);
}
});
}
@Override
protected void onDestroy(){
super.onDestroy();
unregisterReceiver(receiver);
unregisterReceiver(receiver2);
}
和标准广播一样,首先我们需要分别创建MyBroadcastReceiver、MyBroadcastReceiverTwo的实例以及它们对应的IntentFilter的实例,并分别给IntentFilter的实例添加一个action:broadcast(接收的广播的名称),然后调用registerReceiver()方法进行注册,并将对应的实例传进去。
广播发送
在上面的代码中,我们看到声明了Button方法,所以我们需要在对应的activity_main.xml文件里新增按钮代码
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<Button
android:id="@+id/send_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Send Button"
/>
</LinearLayout>
和标准广播发送sendBroadcast(参数1)相比,可以看到发送有序广播的方法为sendOrderedBroadcast(参数1,参数2),参数1仍然为Intent,参数2是一个与权限相关的字符串,在此我们可以把它置成null。
编译结果
编译运行工程,点击Send Button按钮,我们可以在Logcat里查看到接收器的优先级高低。
把intentFilter1、intentFilter2的Priority分别设置为200和100。
2021-06-02 12:13:07.007 6896-6896/com.example.custombroadcast D/Broadcast received: MyBroadcastReceiver
2021-06-02 12:13:07.012 6896-6896/com.example.custombroadcast D/Broadcast received: MyBroadcastReceiverTwo
把intentFilter1、intentFilter2的Priority分别设置为100和200。
2021-06-02 12:15:14.747 7012-7012/com.example.custombroadcast D/Broadcast received: MyBroadcastReceiverTwo
2021-06-02 12:15:14.760 7012-7012/com.example.custombroadcast D/Broadcast received: MyBroadcastReceiver
截断
在这里我们把MyBroadcastReceiver设置成高优先级接收器,在MyBroadcastReceiver的onReceive()方法中调用abortBroadcast()方法,这样就截断了这条广播了。我们在Logcat中看不到打印的MyBroadcastReceiverTwo信息。
2021-06-02 12:23:50.331 7162-7162/com.example.custombroadcast D/Broadcast received: MyBroadcastReceiver
注销
当然,我们最后一定不要忘了取消注册。我们可以通过调用unregisterReceiver()方法来实现。至此,Android的标准广播发送就完成了。
网友评论