全局广播:发出去的广播可以被任何应用程序接收到
本地广播:发出去的广播只能被本应用程序接收到,一般使用LocalBroadcastManager对广播进行管理。
注册广播的方式一般有两种:
动态注册广播监听
新建一个类,让它继承自BroadcastReceiver并重写父类的onReceive()方法就行了。当广播到来时,onReceive()方法会得到执行,开发者就可以在这个方法中进行处理相应的逻辑。
//动态注册广播
IntentFilter myIntentFilter = new IntentFilter();
myIntentFilter.addAction(Constant.ACTION_NAME);
registerReceiver(new MyReceiver(), myIntentFilter);
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//相应逻辑处理
}
}
静态注册广播监听
动态注册广播缺点:动态注册的广播接收器可以自由的控制注册于注销,在灵活性方面有很大的优势,但是它也存在一个缺点,即必须要在程序启动之后才能接收广播。
静态注册就可以很好的弥补这个缺点,想要使用静态注册必须满足两点:
静态注册同样是要新建一个类继承BroadcastReceiver并重写onReceive()方法
,还需要在AndroidManifest.xml中将这个广播接收器的类名注册进去
。public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//相应逻辑处理
}
}
AndroidManifest.xml
<receiver android:name=".MyReceiver"/>
Android中广播接收器主要可分两种类型:
标准广播
标准广播是一种完全异步执行的广播,在广播发出去之后,所有的广播接收
器几乎都会在同一时刻接收到这条消息,因此它们之间无任何先后顺序可言。这种广播的效率会比较高,但同时也意味着它是无法被截断的。
有序广播
有序广播则是一种同步执行的广播,在广播发出去之后,同一时刻只会有一个广播接收器能够收到这条消息,当这个广播接收器中的逻辑执行完毕后,广播才会继续传递。所以此时的广播接收器是有先后顺序的,优先级高的广播接收器就可以先接收到广播消息,并且前面的广播接收器还可以截断正在传递的关公,这样的广播接收器就无法接收到消息了。
发送标准广播
1.先定义一个广播接收器来准备接受此广播
public static class MyBroadcast extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "接收到了自定义广播", Toast.LENGTH_SHORT).show();
}
}
2.在AndroidManifest.xml中注册这个广播接收器
<receiver android:name=".MyBroadcast">
<intent-filter>
<action android:name="com.example.mybroadcast" />
intent-filter>
receiver>
3.发送一个广播
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("com.example.mybroadcast");
sendBroadcast(intent);
}
});
发送有序广播
为了直观的研究有序广播,我又新建了一个项目。这个项目的内容和之前的一样
(广播接收器名为 MyBroadcast_B
)
发送有序广播只需要改动一行代码,即将sendBroadcast()方法改成sendOrderedBroadcast()方法。sendOrderedBroadcast()方法接收两个参数,第一个仍是Intent,第二个参数是与权限相关的字符串,这里传入null就行了
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("com.example.mybroadcast");
sendOrderedBroadcast(intent, null);
}
});
通过android:priority属性给广播接收器设置优先级,从而设定广播接收器的先后顺序,优先级比较高的接收器就可以先收到广播。
<receiver android:name=".MyBroadcast_B">
<intent-filter android:priority="100">
<action android:name="com.example.mybroadcast" />
intent-filter>
receiver>
既然已经获得了优先权,那么我就可以让MyBroadcastReceive选择是否允许广播继续传递了,可以在onReceive()
方法中添加abortBroadcast()
方法,用来截断广播。
public static class MyBroadcast_B extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "接收到了自定义广播", Toast.LENGTH_SHORT).show();
/*当MyBroadcast_B 接收到消息后 并截断。
*此时MyBroadcast将不会再接收到广播
*/
abortBroadcast();
}
}
全局广播安全性
为了提高全局广播的安全性,一般会增加权限等控制
<permission android:name="com.example.mybroadcast"/>
<receiver android:name=".MyBroadcast_B"
android:exported="true"
android:permission="com.example.mybroadcast">
<intent-filter>
<action android:name="com.example.mybroadcast" />
intent-filter>
receiver>
之前所讲的发送和接收广播都是属于系统全局广播,也就是说发出的广播可以被其他任何应用程序接收到,这样大大降低了安全性。因此Android中引入了一套本地广播机制,使用这个机制发出的广播只能够在应用程序的内部进行传递,并且广播接收器也只接收来自本地应该程序发出的广播,大大的解决了广播的安全性问题。用法并不复杂,主要就是使用了一个LocalBroadcastManager来对广播进行管理,并提供了发送广播和注册广播接收器的方法
public class LocalBroadcastMngActivity extends AppCompatActivity {
private IntentFilter intentFilter;
private LocalReceiver localReceiver;
private LocalBroadcastManager localBroadcastManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_local_broadcast_mng);
localBroadcastManager = localBroadcastManager.getInstance(this);//获取实例
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("com.example.mybroadcast");
localBroadcastManager.sendBroadcast(intent);//发送本地广播
}
});
intentFilter = new IntentFilter();
intentFilter.addAction("com.example.mybroadcast");
localReceiver = new LocalReceiver();
//注册本地广播监听器
localBroadcastManager.registerReceiver(localReceiver, intentFilter);
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(localReceiver);//取消注册
}
}
class LocalReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(LocalBroadcastMngActivity.this, "接收到本地广播", Toast.LENGTH_SHORT).show();
}
}
地广播的用法和之前动态注册广播的用法大致相同,只不过现在首先是通过LocalBroadcastManager
的getInstance()
方法得到了它的一个实例;然后再注册广播接收器的时候调用的是LocalBraodcastManager
的sendBroadcast()
方法,仅此而已。
另外一点还需要说明,本地广播是无法通过静态注册的方式来接收的。
本地广播的优点
可以明确的知道正在发送的广播不会离开我们的程序,因此不需要担心机密数据泄露问题。
其他的程序无法将广播发送到我们程序的内部,因此不需要担心会有安全漏洞的隐患。
发送本地广播比起发送系统全局广播将会更加高效。