前言:
广播作为Android四大组件之一,类似于现实生活中的广播,经常用来传递及处理消息,有时候我们的应用程序需要在特定的情况下执行不同的逻辑,如系统开机,网络状态的变化,电源电量的变化…,这些都需要通过广播来实现。不仅如此,有时候我们还需要为我们的程序自定义广播,实现相应的逻辑功能。广播分为标准广播,有序广播,注册又有动态注册及静态注册,按作用域也有全局广播及本地广播。
1、广播的静态注册与动态注册
广播有静态注册与动态注册两种方式,静态注册是在AndroidManifest.xml中类似于Activity的方式注册,这种注册的优点是程序不用启动也可以接受到广播,缺点也很明显就是不灵活,无法只作用于特定的Activity,也叫常驻型广播。而动态注册则与之相反,如果程序没有启动的话就接受不到广播(因为广播的注册通常是在onCreate()方法中),但这种注册方式比较灵活,可以为特定的Activity注册,也叫非常驻型广播。
2、接受系统广播,监听开机启动
当系统开机的时候,系统会发出一条Action为android.intent.action.BOOT_COMPLETED
的广播,要想监听系统开机启动,需要使用静态注册,这样当系统开机启动的时候,我们的程序没启动也能接受到广播。
编写广播接收器,在onReceiver()中编写我们的逻辑代码
public class BootCompletedReceiver extends BroadcastReceiver {
private static final String TAG = "BootCompletedReceiver";
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG,intent.getAction());
// ...
}
}
静态注册
<receiver android:name=".BootCompletedReceiver" android:enabled="true" <!-- 使这个广播接收器可用 -->
android:exported="true"> <!-- 允许这个广播接收器接受其他程序的广播 -->
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"></action>
</intent-filter>
</receiver>
注意:
- enabled=true表示让这个广播接收器可用,exported=true表示允许这个广播接收器接受本程序以外的广播。
- 为我们的广播接收器添加
android.intent.action.BOOT_COMPLETED
的action,这样才能接受到系统开机启动广播。
完成上面的步骤后还需要为我们的应用添加接受开机启动权限才能接受的系统开机启动的广播:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"></uses-permission>
3、发送标准与有序广播
标准的广播以异步的方式发送,每个接受到广播都是异步的,在这种模式下不能够拦截广播,也就是不能在广播接收器的onReceive()方法中调用abortBroadcast()
,而在有序广播是以同步的方式发送,在广播接收器中就可以调用abortBroadcast()
来拦截广播,使广播不会再下一个广播接收器中受到(可以设置广播接收器的过滤器设置优先级)。
如:
public class MyBroadReceiver extends BroadcastReceiver {
private static final String TAG = "MyBroadReceiver";
public static final String ACTION = "com.lt.demo.MyBroadReceiver";
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG,"current time:"+ SystemClock.currentThreadTimeMillis());
// abortBroadcast(); // 仅有序广播可用
}
}
发送有序广播与无序广播
public class SecondActivity extends AppCompatActivity {
private MyBroadReceiver myBroadReceiver = new MyBroadReceiver();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
registerReceiver(myBroadReceiver,new IntentFilter(MyBroadReceiver.ACTION));
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(myBroadReceiver);
}
// 发送标准(无序)广播
public void sendBroad(View v){
sendBroadcast(new Intent(MyBroadReceiver.ACTION));
}
// 发送有序广播
public void sendOrderedBroad(View v){
sendOrderedBroadcast(new Intent(MyBroadReceiver.ACTION),null);
}
}
4、使用本地广播
前面涉及到的广播(全局广播)使得我们的应用存在一个安全隐患就是我们应用发送广播时带的一些数据会被其他程序截获(其他程序接受到我们发送的广播),也可能是我们的广播接收器被其他恶意程序不断调戏。我们可以使用本地广播来避免以上的安全问题。本地广播指的是专属于我们自己程序的广播,它不会被其他程序所接受,也不会接受到其他程序的恶意广播。
本地广播的使用很简单,将动态注册广播的注册与注销方法更换一下就好了,如:
public class SecondActivity extends AppCompatActivity {
private MyBroadReceiver myBroadReceiver = new MyBroadReceiver();
private LocalBroadcastManager mLocalBroadcastManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
mLocalBroadcastManager = LocalBroadcastManager.getInstance(this);
registerReceiver(myBroadReceiver,new IntentFilter(MyBroadReceiver.ACTION));
}
@Override
protected void onDestroy() {
super.onDestroy();
mLocalBroadcastManager.unregisterReceiver(myBroadReceiver);
}
public void sendBroad(View v){
sendBroadcast(new Intent(MyBroadReceiver.ACTION));
}
public void sendOrderedBroad(View v){
sendOrderedBroadcast(new Intent(MyBroadReceiver.ACTION),null);
}
}
可以看出只需将动态注册的registerReceiver及unregisterReceiver方法的调用者换成LocalBroadcastManager的实例即可,同时由于本地广播只为我们自己的程序服务,它的生命周期也属于我们的程序,是非常驻型广播,只能使用动态注册的方式注册。