安卓Broadcast是一种用于在应用程序之间或者系统和应用程序之间传递消息的机制。它可以让你的应用程序响应一些特定的事件,比如电池电量变化、网络状态变化、开机完成等。安卓Broadcast有以下几个特点:
- 它是一种异步的通信方式,不需要等待接收方的回复。
- 它可以跨进程或者跨应用程序发送和接收消息,实现不同组件之间的解耦。
- 它可以通过设置权限或者优先级来控制广播的发送和接收,保证安全性和效率。
为了使用安卓Broadcast,你需要了解以下几个概念:
- 广播发送者(Broadcast Sender):负责发送广播消息的组件,可以是系统或者应用程序中的任何一个组件,比如Activity、Service、ContentProvider等。广播发送者可以通过调用sendBroadcast()、sendOrderedBroadcast()或者sendStickyBroadcast()方法来发送不同类型的广播。
- 广播接收者(Broadcast Receiver):负责接收广播消息的组件,必须继承自BroadcastReceiver类,并重写onReceive()方法来处理收到的广播消息。广播接收者可以通过在AndroidManifest.xml文件中静态注册,或者在代码中动态注册。静态注册的广播接收者可以在应用程序未启动时就接收到广播,而动态注册的广播接收者必须在应用程序运行时才能接收到广播。
- 广播类型(Broadcast Type):根据广播的发送方式和接收顺序,可以分为以下三种类型:
- 标准广播(Normal Broadcast):一种完全异步的广播,广播发送者一旦发送广播,所有注册了相应IntentFilter的广播接收者几乎同时接收到这条广播,没有先后顺序,也不能被截断。这种广播效率高,但是安全性低。
- 有序广播(Ordered Broadcast):一种同步的广播,广播发送者一旦发送广播,系统会根据广播接收者的优先级依次将广播传递给每个接收者,高优先级的接收者先收到,并且可以对广播进行修改或者终止。这种广播效率低,但是安全性高。
- 粘性广播(Sticky Broadcast):一种特殊的标准广播,它会一直保留在系统中,即使在广播发送后,后续注册了相应IntentFilter的广播接收者也能够接收到这条广播。这种广播适合用于某些重要的或者不经常变化的信息,比如电池电量、网络状态等。但是由于它会占用系统资源,并且可能造成数据不一致的问题,所以官方不推荐使用,并且在API 21后已经被废弃。
下面是一个简单的示例,演示了如何使用标准广播和有序广播来实现一个自定义事件的通知功能。假设我们有两个应用程序A和B,都需要监听一个名为com.example.MY_EVENT的自定义事件,并且显示相应的Toast消息。我们可以按照以下步骤来实现:
- 在应用程序A中,创建一个名为MySenderActivity的活动类,用于发送标准广播和有序广播。在布局文件中添加两个按钮,分别对应两种类型的广播。在按钮的点击事件中,创建一个Intent对象,并设置其action为com.example.MY_EVENT。然后调用sendBroadcast()或sendOrderedBroadcast()方法来发送不同类型的广播。
- 在应用程序A中,创建一个名为MyReceiverA的广播接收者类,继承自BroadcastReceiver,并重写onReceive()方法。在onReceive()方法中,获取广播的action,并判断是否为com.example.MY_EVENT。如果是,就显示一个Toast消息,内容为"App A received the broadcast"。然后根据广播的类型,决定是否调用abortBroadcast()方法来终止广播的传递。
- 在应用程序A中,修改AndroidManifest.xml文件,添加以下内容:
- 申请一个自定义的权限,名为com.example.MY_PERMISSION。
- 静态注册MyReceiverA,并设置其intent-filter的action为com.example.MY_EVENT,优先级为100。同时设置其permission为com.example.MY_PERMISSION,表示只有拥有该权限的广播接收者才能接收到该广播。
- 将MySenderActivity设置为启动活动。
- 在应用程序B中,创建一个名为MyReceiverB的广播接收者类,继承自BroadcastReceiver,并重写onReceive()方法。在onReceive()方法中,获取广播的action,并判断是否为com.example.MY_EVENT。如果是,就显示一个Toast消息,内容为"App B received the broadcast"。
- 在应用程序B中,修改AndroidManifest.xml文件,添加以下内容:
- 申请com.example.MY_PERMISSION权限,表示该应用程序可以接收到带有该权限的广播。
- 静态注册MyReceiverB,并设置其intent-filter的action为com.example.MY_EVENT,优先级为50。
下面是应用程序A和B的代码和布局文件:
应用程序A:
MySenderActivity.java
package com.example.broadcastsender;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MySenderActivity extends AppCompatActivity {
private Button normalButton;
private Button orderedButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_sender);
normalButton = findViewById(R.id.normal_button);
orderedButton = findViewById(R.id.ordered_button);
normalButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//发送标准广播
Intent intent = new Intent("com.example.MY_EVENT");
sendBroadcast(intent);
}
});
orderedButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//发送有序广播
Intent intent = new Intent("com.example.MY_EVENT");
sendOrderedBroadcast(intent, null);
}
});
}
}
MyReceiverA.java
package com.example.broadcastsender;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class MyReceiverA extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//获取广播的action
String action = intent.getAction();
//判断是否为自定义事件
if ("com.example.MY_EVENT".equals(action)) {
//显示Toast消息
Toast.makeText(context, "App A received the broadcast", Toast.LENGTH_SHORT).show();
//根据广播类型决定是否终止广播
if (isOrderedBroadcast()) {
abortBroadcast();
}
}
}
}
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.broadcastsender">
<!--申请自定义权限-->
<permission android:name="com.example.MY_PERMISSION"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.BroadcastSender">
<!--静态注册广播接收者-->
<receiver
android:name=".MyReceiverA"
android:permission="com.example.MY_PERMISSION">
<intent-filter android:priority="100">
<action android:name="com.example.MY_EVENT"/>
</intent-filter>
</receiver>
<!--设置启动活动-->
<activity android:name=".MySenderActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
最后一次更新于August 17th, 2023