BroadcastReceiver是一种消息型组件,用于在不同组件乃至不同的应用之间传递消息.广播有两种注册方式,静态注册和动态注册.广播可以用来实现低耦合的观察者模式,广播一般来说不需要停止,它没有停止的概念.
- 广播的注册方式
- 广播的种类
一.广播的注册方式
1.静态注册
静态注册是指在AndroidManifest中注册广播,这种广播在应用安装时会被系统解析,此种形式的广播不需要应用启动就可以收到相应的广播.
<receiver android:name=".MyBroadcast"></receiver>
2.动态注册
动态注册是通过Context.registerReceiver()来实现,并且在不需要的时候可以通过Context.unregisterReceiver()来解除广播,此种形态的广播必须要应用启动才能注册并接收广播.
二.广播的种类
1.普通广播
普通广播是完全异步执行的广播,当广播发出后,基本上所有的广播接收器都会同时收到这条广播,因此他们接收的先后次序是随机的.另外接收器不能截断普通广播.普通广播的示例图如下:
(1)接收系统广播
自定义一个接收器类并继承BroadcastReceiver,然后具体实现在onReceive()方法.需要注意的是BroadcastReceiver的生命周期只有10秒左右,因此onReceive()不能做一些耗时的操作,应该发送给Service,由service来完成,另外onReceive()不要开启子线程.
举例:当网络状态发生变化时,系统会发送一条值为android.net.conn.CONNECTIVITY_CHANGE的广播
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("android.net.conn.CONNECTIVITY_CHANGE")) {
//接收网络状态发生变化发送的广播
}
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//动态注册
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
mMyReceiver = new MyReceiver();
registerReceiver(mMyReceiver,intentFilter);
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(mMyReceiver);
}
//静态注册
<receiver android:name=".MyReceiver">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
</intent-filter>
</receiver>
(2)发送自定义广播
自定义广播就是利用Intent把要发送的广播值传入,再利用sendBroadcast()方法把广播发送出去,广播接收器就能接收到这条广播.
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"接收到自定义广播",Toast.LENGTH_SHORT).show();
}
}
<receiver android:name=".MyReceiver">
<intent-filter>
<action android:name="com.example.test.My_BROADCAST"/>
</intent-filter>
</receiver>
public void click(View view) {
Intent intent = new Intent("com.example.test.My_BROADCAST");//指明要发送的广播值
sendBroadcast(intent);
}
2.有序广播
有序广播是一种同步执行的广播,广播发出后,在同一个时刻只会有一个广播接收器能够收到这条广播消息,当这个广播接收器中的逻辑执行完毕后,广播才会继续传递,所以此时的广播接收器是有先后顺序的,优先级(priority)高的广播接收器会先收到消息,有序广播可以被接收器截断,使得后面的接收器无法收到它,有序广播的工作流程如图所示:
发送有序广播通过sendOrderBroadcast()方法,该方法有两个参数,第一个参数是intent,第二个参数是一个与权限相关的字符串,这里传入null.
public void click(View view) {
Intent intent = new Intent("com.example.test.My_BROADCAST");//指明要发送的广播值
sendOrderedBroadcast(intent,null);
}
有序广播通过priority属性来定义优先级,值越大,优先级越高.
<receiver android:name=".MyReceiver">
<intent-filter android:priority="100">//设定有序广播优先级,值越大,优先级越高
<action android:name="com.example.test.My_BROADCAST"/>
</intent-filter>
</receiver>
有序广播通过abortBroadcast()方法来截断广播,使该条广播不再向下面传递.
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//逻辑处理
//截断广播,不再向下传递
abortBroadcast();
}
}
3.本地广播
上面说到的普通广播和有序广播都是全局广播,也就是发出的广播能被其它应用程序接收到,我们也能接收到其它应用程序发送的广播.为了能够简单的解决全局广播可能带来的安全性问题,Android引入了一套本地广播机制,使用这个机制发送的广播只能够在应用程序内部进行传递,且广播接收器也只能接收本应用程序发出的广播.
本地广播主要使用了LocalBroadcastManager来对广播进行管理,需要注意的是本地广播只能使用动态注册的方式注册.代码示例如下:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mLocalBroadcastManager = LocalBroadcastManager.getInstance(this);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("com.example.test.My_BROADCAST");
mMyReceiver = new MyReceiver();
mLocalBroadcastManager.registerReceiver(mMyReceiver,intentFilter);
}
public void click(View view) {
Intent intent = new Intent("com.example.test.My_BROADCAST");//指明要发送的广播值
mLocalBroadcastManager.sendBroadcast(intent);
}
@Override
protected void onDestroy() {
super.onDestroy();
mLocalBroadcastManager.unregisterReceiver(mMyReceiver);
}
4.粘性广播
通过Context.sendStickyBroadcast()方法可发送粘性广播,该广播会一直滞留,当有匹配该广播的接收器被注册后,该接收器就会收到该条广播,需要注意的是,粘性广播需要android.permission.BROADCAST_STICKY权限.
sendStickyBroadcast()只保留最后一条广播,并且一直保留下去,这样即使已经有广播接收器处理了该广播,一旦又有匹配的广播接收器被注册,该粘性广播仍会被接收。如果只想处理一遍该广播,可通过removeStickyBroadcast()方法来实现。接收粘性广播的过程和普通广播是一样的,就不多介绍了。