BroadCastReceiver总结
BroadCastReceiver是Android的四大组件之一,主要功能就是发送消息,监听消息,然后根据业务进行逻辑处理,可以在应用内部,也可以是应用之间使用。从应用内部的消息,数据传递这个功能来说,现如今有很多开源的框架可以实现,比如EventBus 或者使用观察者模式自定义封装一个消息发送机制,也都挺好用的。当然今天的主角是BroadCastReceiver。
一.静态注册:
1.写一个广播集成BrocastReceiver
public class MyReceiver1 extends BroadcastReceiver {
public static final String ACTION1="com.example.liukang.mybroadcastprojrct.test";
@Override
public void onReceive(Context context, Intent intent) {
if (intent!=null){
String r1 = intent.getStringExtra("MyReceiver1");
Toast.makeText(context,"我接收到了"+r1,Toast.LENGTH_LONG).show();
Log.e("TAG",r1);
//abortBroadcast(); 有序广播时候,优先级高的可以接收,进行判断处理是否往下传递
}
}
}
2.在清单文件中注册一下:
<receiver
android:name=".MyReceiver1"
android:exported="true">//是否能接收其他APP发送的消息
<intent-filter android:priority="100">//有序广播优先级使用,越大越高
<action android:name="ACTION_RECEIVER" />
<category android:name="category" />
</intent-filter>
</receiver>
3.发送广播:
Intent intent = new Intent();
intent.setAction("ACTION_RECEIVER"); //一定对应
intent.addCategory("category"); //不写即是默认 可以匹配;但是写了,那么清单文件MyReceiver1注册的必须得有,否则不通过
intent.setComponent(new ComponentName("com.example.liukang.mybroadcastprojrct",
"com.example.liukang.mybroadcastprojrct.MyReceiver1")); // Android 8.0之后必须指定包名,以及包名.类名
intent.putExtra("MyReceiver1", "MyReceiver1广播");
sendBroadcast(intent);
//sendOrderedBroadcast(intent,null); 发送有序广播
二:动态注册
1.写一个类继承
public class MyMainReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent != null) {
String main = intent.getStringExtra("main");
Toast.makeText(MainActivity.this, "这是MyMainReceiver广播接收的数据:" + main, Toast.LENGTH_LONG).show();
}
}
}
2.动态注册
MyMainReceiver myMainReceiver = new MyMainReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("MyMainReceiver");
registerReceiver(myMainReceiver, filter);
3.发送广播:
//发送Main广播
Intent intent =new Intent();
intent.setAction("MyMainReceiver");
intent.putExtra("main","123456");
sendBroadcast(intent);
4.取消注册
unregisterReceiver(myMainReceiver );
三:本地广播:只是APP内部使用,保证信息传递的安全。
1.自定义广播
public class MyFirstActiivtyReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
if (intent!=null){
String r2 = intent.getStringExtra("r2");
Toast.makeText(context,r2,Toast.LENGTH_LONG).show();
Log.e("TAG",r2);
}
}
}
//本地动态注册
receiver=new MyFirstActiivtyReceiver();
IntentFilter filter=new IntentFilter();
filter.addAction("ACTION_TEST");
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(this);
localBroadcastManager.registerReceiver(receiver,filter);
//本地发送:
Intent intent =new Intent();
intent.setAction("ACTION_TEST");
intent.putExtra("r2","123456");
localBroadcastManager.sendBroadcast(intent);
//取消注册
localBroadcastManager.unregisterReceiver(receiver);
四 注意事项:
1.静态注册的全局广播是一直处于监听状态,消耗性能。一般最好使用动态注册,灵活,强大。在开发中大多的广播接收者是将接收道的数据进行业务处理,所以一般是内部类形式的接收者,这种形式只能是动态注册。
2.注册在onstart里面,取消注册在onDestroy中,减少性能开支,并且可以防止内存泄漏。
3.对于静态注册的广播,8.0以及以后的版本,是需要指定包名以及包名.类名的。
4.onReceiver() 方法是运行在UI中的并且不允许开一个新的线程,所以最好不要进行耗时操作,否则超过10s就会ANR;
可以开启一个服务,在服务里执行一些耗时操作。
5.静态广播分为有序,无序。有序特点:按优先级从高到低逐层传递,所以高层可以优先终止广播的继续传递,abortBroadcast();
6.静态注册的广播如果有intentFilter 则export默认是true,可以接收其他APP发送的广播。否则为false.就只能接收内部的广播;
7.如果监听一些系统的广播,有些是需要配置权限的。比如开机的Action:
下面是系统常用的Action
8.自定义权限:
清单文件(接收方):
<permission android:name="com.example.broadcast.permission"
android:protectionLevel="normal" /> //signature 则发送方和接收方必须得用一样的签名文件否则收不到
<receiver android:name=".MyRecevicer1"
android:permission="com.example.broadcast.permission">
<intent-filter>
<action android:name="action1" />
</intent-filter>
</receiver>
动态注册(接收方)
MyRecevicer1 receiver = new MyRecevicer1();
IntentFilter filter = new IntentFilter("action1");
filter.addCategory(Intent.CATEGORY_DEFAULT);
//注册receiver时,直接指定发送者应该具有的权限。不然外部应用依旧可以触及到receiver
registerReceiver(receiver, filter, permission, null);
发送广播(发送方):
Intent intent = new Intent("action1");
intent.putExtra("r1", "receiver");
sendBroadcast(intent, permission);
权限对应不上是接收不到的,使用的不多。一般为了防止外部应用的调用,可以用本地广播,或者export设置false;
总体来说常用的就这些吧,以后用到了在添加。如果有啥错误的地方,还请指点一二。