广播broadcast
根据概念的分类,广播可以分为标准广播和有序广播。
- 标准广播:是完全异步执行的广播,每发出一条标准广播,所有的应用程序在同一时刻收到这条广播。他们之间没有先后顺序,这类广播优点是效率高,缺点是无法拦截广播。
- 有序广播 : 是指一种同步执行的广播,在广播发出之后,同一时刻只会有一个广播接收器能够收到这条广播消息,当这个广播接收器中的逻辑执行完毕后,广播才会继续传递,有序广播的接收是有先后顺序的,优先级高的广播先接收,并且前面的广播接收器可以进行拦截正在传递的广播。这样优先级低的广播就接收不到这条广播。
根据系统的分类可以分为系统全局广播和本地广播两种
- 系统全局广播
即发出的广播可以被其他任何应用程序接收到,并且我们也可以接收到来自其他任何应用的广播。这样会引起安全性问题,比如我们发送一些携带关键性数据的广播有可能被其他的应用程序截获,或者其他的程序不停地向我们的广播接收器里发送各种垃圾广播。系统广播实现是通过Context提供的sendBroadcast()/sendOrderedBroadcast(),unregisterReceiver(),registerReceiver()来动态注册,同时也支持在Androidmanifest文件的静态注册。
- 本地广播
解决了系统广播的安全性问题,这类广播只能够在应用程序的内部进行传递,并且广播接收器也只能接收来自本应用程序发出的广播。提供了LocalBroadcastManager对广播进行管理,提供sendBroadcast()/sendOrderedBroadcast(),unregisterReceiver(),registerReceiver() 发送和注册广播。本地广播只能够进行动态注册,不支持静态注册。
系统全局广播
广播接收器的创建
如下代码所示:
class MyBroadcastReceiver extends BroadcastReceiver{
public void onReceiver(Context context, Intent intent){
//xxxxx any broadcast is sent via intent.
}
}
注册广播可以用动态注册或者静态注册来指定接收的广播类型。
动态注册就是在代码中实现:
- 首先借助IntentFilter 筛选监听的广播类型。
IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
intentFilter.addAction("andorid.net.conn.CONNECTIVITY_CHANGE");
- 其次使用registerReceiver()的参数传递完成注册。
registerReceiver(myBroadcastReceiver, intentFilter);
- 同时在OnDestory方法里添加unregisterReceiver(myBroadcastReceiver, intentFilter);
静态注册是在AndroidManifest.xml中实现
与<Activity>标签类似,都是<application>的子标签,都通过android:name属性将intent和类链接。
<receiver
android:name=".MyBroadcastReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.begin.broadcasttest.MY_BROADCAST"/>
</intent-filter>
</receiver>
自定义系统全局广播
自定义广播实现步骤如下
- 1. 首先在布局文件中定义一个按钮,用于作为发送广播的触发点,在mainActivity中在按钮的点击事件中
借助Intent 发送自定义的广播通过Context的sendBroadcast()/sendOrderedBroadcast()方法将广播发送出去
- 标准广播的发送:参数是Intent
Intent mybroadcastIntent = new Intent(“com.example.test.MY_BROADCAST”);
sendBroadcast(mybroadcastIntent);
- 有序广播的发送:第一个参数是Intent,第二个参数是与权限相关的字符串。
Intent mybroadcastIntent = new Intent(“com.example.test.MY_BROADCAST”);
sendOrderedBroadcast(mybroadcastIntent,null);
- 2. 其次创建自定义广播的接收处理,这步操作跟接收系统广播步骤一样,可以通过动态或者静态方式注册并创建BroadcastReceiver实例来进行目标接收。
- 有序广播优先级设置:如果自定义广播是有序广播,可以通过如下代码设置广播接收器的优先级。
<receiver
android:name=".MyBroadcastReceiver"
android:enabled="true"
android:exported="true">
<intent-filter android:priority="100">
<action android:name="com.begin.broadcasttest.MY_BROADCAST"/>
</intent-filter>
</receiver>
- 如何拦截有序广播
当你设置广播优先级后,在前面的广播接收完后,可以通过abortBroadcast()方法拦截这条广播,那么后面的就无法接收了。
本地广播
本地广播的发送和注册都统一有LocalBroadcastManager来管理。- 创建本地广播,在布局页面创建一个按钮用来触发广播,在按钮的监听事件中发送广播,动态注册广播。
Public LocalBroadcastManager localBCManager;
public LocalReceiver receiver;
.....
//send local Broadcast
final Button sendBtn=(Button)findViewById(R.id.sendBroadcastBtn);
localeBCManager = LocaleBCManager.getInstance(this);
sendBtn.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View view) {
Intent intentlocal=new Intent("com.begin.broadcasttest.MY_LOCAL_BRODCAST");
localeBCManager.sendBroadcast(intentlocal);
}
});
//动态注册广播
receiver = new LocaleBroadcastReceiver();// inner class extends LocalReceiver
IntentFilter localFilter = new IntentFilter();
localFilter.addAction("com.begin.broadcasttest.MY_LOCAL_BRODCAST");
localBCManager.registerReceiver(receiver, localFilter);
@Override
protected void onDestroy() {
super.onDestroy();
localBCManager.unregisterReceiver(localReceiver);
}
class LocalReceiver extends BroadCastReceiver{
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "", Toast.LENGTH_SHORT).show();
}
}