(1)静态注册
AndroidManifest.xml
MyBroadCastReceiver
public class MyBroadCastReceiver extends BroadcastReceiver {
private static final String TAG = "MyBroadCastReceiver";
@Override
public void onReceive(Context context, Intent intent) {
Log.i(TAG, "广播启动了"+intent.getStringExtra("name"));
}
}
MainActivity
mStartBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent();
intent.setAction("com.mybroadCastReceiver");
intent.putExtra("name", "静态注册");
sendBroadcast(intent);
}
});
在Android8.0之前静态注册广播还是可以接收到广播的,但是在Android8.0开始,静态注册无法再接收到广播,需要修改MainActivity中的代码
mStartBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//AndroidManifest.xml中的action
Intent intent=new Intent("com.mybroadCastReceiver");
//第一个参数:包名 第二个参数:广播接收器的路径
intent.setComponent(new ComponentName("collect.pingshow.com.demo3","collect.pingshow.com.demo3.MyBroadCastReceiver"));
intent.putExtra("name", "静态注册");
sendBroadcast(intent);
}
});
(2)动态注册
MainActivity
//动态注册广播
@Override
protected void onResume() {
super.onResume();
myBroadCastReceiver = new MyBroadCastReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("com.mybroadCastReceiver");
registerReceiver(myBroadCastReceiver, filter);
}
//启动广播
case R.id.startBtn3:
Intent intent2 = new Intent();
intent2.setAction("com.mybroadCastReceiver");
intent2.putExtra("name", "动态注册");
sendBroadcast(intent2);
break;
动态注册广播后,还需要在程序退出时,将广播销毁,不然会导致内存泄漏
@Override
protected void onPause() {
super.onPause();
//解绑广播
unregisterReceiver(myBroadCastReceiver);
}
(3)动态广播最好在onResume()和onPause注销。在onResume()注册、onPause()销毁是因为app在死亡前一定会被执行onPause,就可以保证广播在App死亡前一定会被注销,防止内存泄漏。
(1)静态注册:不受任何生命周期组件的影响,应用程序关闭后,如有广播来,程序仍会被系统调用。缺点:耗电、费内存
(2)动态注册:跟随组件的生命周期变化,程序退出,广播也就结束了
(1)普通广播
Intent intent = new Intent();
intent.setAction("com.mybroadCastReceiver");
sendBroadcast(intent);
若被注册了的广播接收者中注册时intentFilter的action与上述匹配,就会回调onReceive方法
(2)系统广播
当使用系统广播时,只需要在注册广播接受者时定义相关的action就可以,不需要手动发送广播,当系统有相关操作就会自动进行系统广播
(3)有序广播
发送出去的广播被广播接受者按照先后顺序进行接收
按照Priority属性的值从大到小排序的
Priority属性值相同的,动态注册的广播优先
有序广播的发送方式
Intent intent = new Intent();
intent.setAction("com.mybroadCastReceiver");
sendOrderedBroadcast(intent);
(4)粘性广播
由于在Android5.0 & API 21中已经失效,所以不建议使用
(5)App应用内广播
在Android中,广播默认是可以跨App(跨进程)直接通信。因为exported属性默认是true 由于广播默认是跨进程,同时广播是根据发送意图Intent和意图过滤器Intent-filter进行匹配判断,从而决定BroadcastReceiver的onReceiver方法是否回调,这可能会出现以下问题:如果其他App发出来的广播Intent与当前App的Intent-filter相匹配,由此就会导致当前App不断接受广播并处理。如果不法分子知道了App的Intent-filter,就有可能通过此漏洞进行一些不良信息的推送,会影响App的安全性
针对以上问题的解决方案
将全局广播设置为局部广播
1.注册广播时,将exported属性设置为false,使得非本app内部发出的此广播不被接受
2.在广播发送和接收时,增设相应的权限permission
使用本地广播
对于LocalBroadcastManager方式发送的应用内广播,只能通过LocalBroadcastManager动态注册,不能静态注册。
myBroadCastReceiver = new MyBroadCastReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("com.mybroadCastReceiver");
LocalBroadcastManager instance = LocalBroadcastManager.getInstance(this);
//注册广播
instance.registerReceiver(myBroadCastReceiver,filter);
//销毁广播
instance.unregisterReceiver(myBroadCastReceiver);