理解广播与广播接收器
广播事件处理属于 系统级的事件处理(一般事件处理属于View级的事件处理)
Context
BroadcastReceiver
常见的系统广播
注册广播接收器
<receiver android:name="com.example.mybroadcast.MyReceiver1">
<intent-filter>
<action android:name="com.example.mybroadcast.MyReceiver1.action"/>
intent-filter>
receiver>
静态注册的话,要注意android8.0以上要加入(不然会失效):
intent.setPackage(getPackageName());
MyBroadcastReceiver receiver=new MyBroadcastReceiver(action);
IntentFilter filter=new IntentFilter(action);
registerReceiver(receiver,filter);
我们接下来要做的是,一个进程发送一个广播给另一进程接收广播。
嗯,今天很奔溃,看着视频学习,但是代码打错一点点,所以就搞了好久,所以在你们在自己写的时候,代码不要写错!代码不要写错!代码不要写错!重要的事情说三遍。
好了,进入正题,既然我们要跨进程的广播,那我们就必须要创建两个应用。
首先我们进入第一个应用(广播接收器)要静态的注册广播。
写一个类继承BroadcastReceiver。建议不要创建一个类,然后自己写继承。可以使用便捷一点而且不容易写错的方法:
1,File->new->Other->Broadcast Receiver
2,在要接收广播的应用文件上右键,重复第一步的步骤。
/**
* 静态注册广播
*/
public class MyReceiver extends BroadcastReceiver {
public MyReceiver() {
Log.e("TAG","MyReceiver 静态广播接收构造器");
}
@Override
public void onReceive(Context context, Intent intent) {
Log.e("TAG","MyReceiver 静态广播接收");
if("456789".equals(intent.getStringExtra("action"))){
Log.e("TAG","456789");
}
}
}
(构造器是自己添加的,为了方便测试)
当你创建号BroadcastReceiver子类时,配置文件会生成:
<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="true">
receiver>
之后就其里面就可以添加接收的广播:
<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="123456"/>
intent-filter>
receiver>
我们在这里接收 行为 叫132456的广播。我们的静态广播接收应用就完成了。
之后我们来做一个发送广播的应用(为了测试让广播接收应用接收到):
xml文件就不写了吧…也就只有按钮。这里也就是创建一个方法,然后点击按钮,然后运行这个方法。
//发送一般广播
public void sendNormalBC(View view){
Log.e("TAG","发送一般广播");
Intent intent=new Intent("123456");
intent.setPackage(getPackageName());
intent.putExtra("action","456789");
sendBroadcast(intent);
}
intent在这里的作用就是发送给一个“123456”的广播。然后装载数据名为“action”,里面数据是“456789”。之后就发送广播。
(打印结果和代码中有一点点不一样不要在意)
跟上面的内容差不多,不同的是我们不用再配置文件里添加代码。
也就是我们要动态的去添加广播接收器。
首先我们来看动态注册广播接收器代码:
private MyReceiver2 mr2=null;
public void registBC(View view){
if(mr2==null) {
//创建receiver对象
mr2 = new MyReceiver2();
//创建过滤器对象
IntentFilter filter = new IntentFilter("123");
//注册广播
registerReceiver(mr2, filter);
}
}
//解注册广播接收器
public void unRegistBC(View view){
if(mr2!=null){
unregisterReceiver(mr2);
mr2=null;
}
}
创建过滤器对象是:我们要接收的广播为“123”
首先,我们要同样要写一个BroadcastReceiver子类:
public class MyReceiver2 extends BroadcastReceiver {
public MyReceiver2(){
Log.e("TAG","MY receiver1()");
}
@Override
public void onReceive(Context context, Intent intent){
String str=intent.getStringExtra("action");
Log.e("TAG","MY receiver1 onReceive()"+str);
}
}
发送一般广播的代码没变过,只有改为了发送“123”的广播。
//发送一般广播
public void sendNormalBC(View view){
Log.e("TAG","发送一般广播");
Intent intent=new Intent("123");
intent.putExtra("action","456789");
sendBroadcast(intent);
//Toast.makeText(this,"发送一般广播",0).show();
}
静态注册 | 动态注册 | |
---|---|---|
注册方式 | 配置文件 | JAVA代码 |
注册时间 | 应用安装完成/开机。注册时不会创建对象,接收广播才创建。 | 执行registerReceiver(receiver,intentFilter)。注册就创建对象 |
生命结束时间 | 应用卸载。对象执行onReceiver()后就回收 | 执行unregisterReceiver()(activity退出必须解注册),解注册后对象被回收 |
应用场景 | 需要监听的时间为:应用的整个生命过程 | 只服务于某个activity/Service |
(这里简单介绍下吧)
//有序广播
public void sendOrderBC(View view){
Log.e("TAG","发送有序广播");
Intent intent=new Intent("456");
intent.putExtra("action","789");
sendOrderedBroadcast(intent,null);
}
发送有序广播代码(最后一行)第二个参数为权限,写null就可以了。接收器代码没什么变化。
要注意的是:假设静态注册两个广播接收器,动态注册一个广播接收器,发送广播时,动态注册的先接收,静态注册的谁先注册谁先接受。或者静态注册时设置优先值 priority
public void onReceive(Context context, Intent intent) {
Log.e("TAG","MyReceiver3 静态广播接收");
//中断传播
if(isOrderedBroadcast()){
abortBroadcast();
}
}
上面代码是广播接收器的代码,先收到广播的可以中断传播。