1.广播的类型:
- 标准广播(Normal broadcast)是一种完全异步执行的广播,在广播发出之后,所有的广播接收器几乎都会在同一时刻接收到这条广播消息,因此他们之间没有先后顺序。效率比较高,但是不能被截断。
- 有序广播(Ordered broadcast)是一种同步执行的广播,在广播发出之后,同一时刻只能有一个广播接收器能收到消息,当这个广播接收器中的逻辑执行完毕之后,广播才会继续传递。优先级高的广播接收器就会先收到消息,并且可以截断正在传递的广播,这样后面的广播接收器就收不到消息了。
还可以分为系统广播和本地广播:
- 系统全局广播:发出的广播可以被其他任何应用程序接收到,也可以接收到来自其他任何应用程序的广播。
- 本地广播:为了解决系统广播的安全性问题,Android引入了一套本地广播机制,使用这个机制发出的广播只能在应用程序内部进行传递,广播接收器也只能接收来自本应用程序发出的广播。但是已经被弃用了。
This class is deprecated.
LocalBroadcastManager is an application-wide event bus and embraces layer violations in your app: any component may listen events from any other. You can replace usage of LocalBroadcastManager with other implementation of observable pattern, depending on your usecase suitable options may be LiveData or reactive streams.
2.广播的使用
新建项目BroadcastTest项目
(1)动态注册
- 创建广播接收器,继承BroadcastReceiver,重写父类的onReceive()方法
- 创建IntentFilter的实例,添加值为想要监听的广播的action
- 创建广播接收器的实例,调用registerReceiver()方法进行注册
- 取消注册,动态注册的广播接收器需要取消注册
- 声明权限:在AndroidManifest.xml文件中加入权限
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
public class MainActivity extends AppCompatActivity {
private IntentFilter intentFilter;
private NetworkChangeReceiver networkChangeReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//创建IntentFilter的实例,添加值为想要监听的广播的action
intentFilter = new IntentFilter();
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
//创建广播接收器的实例,调用registerReceiver()方法进行注册
networkChangeReceiver = new NetworkChangeReceiver();
registerReceiver(networkChangeReceiver,intentFilter);
}
//取消注册,动态注册的广播接收器需要取消注册
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(networkChangeReceiver);
}
//创建广播接收器,继承BroadcastReceiver,重写父类的onReceive()方法
class NetworkChangeReceiver extends BroadcastReceiver {
@Override
public void onReceive (Context context,Intent intent) {
Toast.makeText(context, "network changes ", Toast.LENGTH_SHORT).show();
}
}
}
(2)静态注册
- 创建广播接收器(可以使用快捷方式)
- 右击com.example.broadcasttest包->New->Other->Broadcast Receiver。Exported属性表示是否允许这个广播接收器接收本程序以外的广播,Enabled属性表示是否启用这个广播接收器。勾选这两个属性,点击Finish。
- 注册广播:静态的广播接收器需要在AndroidManifest.xml文件中注册
由于是快捷方式创建的广播接收器,注册会自动完成。所有的静态广播都是在application标签内的receiver标签里注册的
<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.BroadcastTest">
<receiver
//具体注册哪个广播
android:name=".MyBroadReceiver"
//刚刚勾选的属性
android:enabled="true"
android:exported="true">
</receiver>
- 添加需要监听的广播值
<receiver
android:name=".MyBroadReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
//添加需要监听的广播值
<action android:name="com.example.broadcasttest.MY_BROADCAST" />
</intent-filter>
</receiver>
- 声明权限:在AndroidManifest.xml文件中加入权限
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
3.发送自定义广播
3.1.发送标准广播
- 创建静态的广播接收器
- 在布局中定义Button,作为发送广播的出发点
- 在button的点击事件里加入发送自定义广播的逻辑。
- 创建Intent对象,传入要发送的广播值
- 调用sendBroadcast()方法将广播发送出去
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("android.net.conn.CONNECTIVITY_CHANGE");
sendBroadcast(intent);
}
});
}
3.2.发送有序广播
在发送标准广播的基础上修改即可:
- 发送有序广播
sendOrderedBroadcast()方法接收两个参数,第一个参数是intent,第二个参数是与权限相关的字符串,这里传入null。
sendOrderedBroadcast(intent,null);
- 在注册的时候定义优先级
通过android:priority属性给广播接收器设置优先级
<receiver
android:name=".MyBroadReceiver"
android:enabled="true"
android:exported="true">
<intent-filter android:priority="100">
<action android:name="com.example.broadcasttest.MY_BROADCAST" />
</intent-filter>
</receiver>
- 是否截断广播
在广播接收器中的onReceiver()方法中调用abortBroadcast()方法,表示将这条广播截断,后面的广播接收器就无法接收这条广播。
public class MyBroadReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "received in MyBroadcastReceiver", Toast.LENGTH_SHORT).show();
abortBroadcast();
}
}