BroadcastReceiver是四大组件之一,是为了让开发者更方便的来进行开发的,翻译成中文就是广播接受者。
接收到的广播分为有序广播、无序广播,并且注册监听广播的方式还分静态注册和动态注册。其实接收广播接收者要先从静态监听系统发出的广播来入手更加容易理解。但是我这里就自己介绍自己发送广播和接收广播来配合讲解吧。
1、自己发送和接收无序广播:
(1)发送无序广播:
Intent intent = new Intent();
intent.setAction("ye.da.shen.test");
intent.putExtra("test", "测试");
sendBroadcast(intent);
无论是监听有序广播还是监听无序广播都需要有一个发广播的时候指定的“口令”才能接收的到。这个“口令”的专业术语叫action。上面我写的代码中我intent.setAction就是指明“口令”,所以接收的时候必须写入这个口令。
(2)注册广播接收者:
注册广播接收者分为动态注册和静态注册。两者的区别就是静态注册必须在manifest中写明,而动态注册是不需要。
A:静态注册:
<receiver android:name=".TestReceiver">
<intent-filter>
<action android:name="ye.da.shen.test" />
</intent-filter>
</receiver>
我里面的action就是在发送广播的时候指明的“口令”。
B:动态注册就不需要写上面A的代码了。但是动态需要在界面销毁的时候取消监听。调用unregistReceiver();如下:
private TestReceiver7 receiver7;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_third);
receiver7 = new TestReceiver7();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("ye.da.shen.test3");
registerReceiver(receiver7, intentFilter);
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(receiver7);
}
我直接贴出TestReceiver的代码来进行讲解。
public class TestReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, intent.getStringExtra("test"), Toast.LENGTH_SHORT).show();
}
}
上面的吐司里面的内容就是在发送广播的时候携带的数据,无序广播在广播接收者里面获取到发送出来的数据方式有两种:intent.getExtra() 和intent.getData()。我就不详细讲了。
2、自己发送和接收有序广播:
/**
* 发送有序广播:
* (1)可以设置接收有限级(最大1000,最小-1000),并且由于优先级的不同导致出现以下情况:
* A:优先级高的比优先级低的先收到数据。
* B:同一优先级,如果是同一应用的两个receiver,现在manifest中先注册的先收到;不是
* 是同一应用,先安装到手机上的先收到。
* C:如果优先级高的在收到数据之后,修改了数据的话,优先级低的收到的数据就是修改之后
* 的数据。
* D: 优先级高的如果终止了广播的传递,那么比当前receiver低的receiver就收不到广播了。
*
* (2)获取数据的方式是:
* intent.getExtras();
* intent.getData();
* getResultData()
*
* (3)可以在发送广播的时候指定一个最终的接收者。不需要再manifest中注册,不需要设置优先级,
* 始终会在最后接收到广播,如果之前优先级高的修改了数据的,那么该最终接收者接收到的数据
* 也是修改之后的。如果优先级高的终止了广播,还是能够接收到广播。
*/
public void sendBroadcast2(View view) {
Intent intent = new Intent();
intent.setAction("ye.da.shen.test2");
/**
* 参数:
* intent:
* receiverPermission 接收者的权限,一般为null
* resultReceiver 最终的广播接收者
* scheduler 其实就是handler,一般为null
* initialCode 初始化的码
* initialData 初始化的数据的字符串形式传递
* initialExtras 初始化的数据的集合形式传递
*/
sendOrderedBroadcast(
intent,
null,
new TestReceiver6(),
null,
RESULT_OK,
"测试数据",
null
);
}
(1)静态注册的时候可以在manifest里面设置监听者的优先级,我上面贴出的里面讲解了优先级的概念和影响。我下面贴出manifest注册广播的优先级是怎么设置的:
<receiver android:name=".TestReceiver2">
<intent-filter android:priority="200">
<action android:name="ye.da.shen.test2" />
</intent-filter>
</receiver>
(2)优先级高的可以接收到广播之后,拿出里面携带的数据,并且修改数据之后再放回,那么后面的接受者拿到的数据就是修改之后的,比如:
<receiver android:name=".TestReceiver3">
<intent-filter android:priority="300">
<action android:name="ye.da.shen.test2" />
</intent-filter>
</receiver>
<receiver android:name=".TestReceiver4">
<intent-filter android:priority="250">
<action android:name="ye.da.shen.test2" />
</intent-filter>
</receiver>
//TestReceiver3的优先级比TestReceiver4要高
public class TestReceiver3 extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// getResultData()拿到的数据是“测试”两个字
setResultData(getResultData() + ",数据被TestReceiver3修改了");
}
}
public class TestReceiver4 extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.i("TestReceiver4", getResultData());
//上面的打印会是:"测试,数据被TestReceiver3修改了"
}
}
(3)优先级高的可以在接收到广播之后,终止广播继续向下传递,调用abortBroadcast();
<receiver android:name=".TestReceiver3">
<intent-filter android:priority="300">
<action android:name="ye.da.shen.test2" />
</intent-filter>
</receiver>
<receiver android:name=".TestReceiver4">
<intent-filter android:priority="250">
<action android:name="ye.da.shen.test2" />
</intent-filter>
</receiver>
//TestReceiver3的优先级比TestReceiver4要高
public class TestReceiver3 extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// getResultData()拿到的数据是“测试”两个字
setResultData(getResultData() + ",数据被TestReceiver3修改了");
abortBroadcast();
}
}
public class TestReceiver4 extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.i("TestReceiver4", getResultData());
}
}
上面的TestReceiver4的是不会走打印的,因为根本就接收到广播。
(4)有序广播可以指定最终接收者,一旦指定之后,即使优先级高的终止了向下继续传递广播,最终接受者还是能够接收到广播。在2哪里我贴出的一段代码中,就指明TestReceiver6为最终接收者,那么他就一定能在最后接收到广播,并且不需要设置优先级也不需要再manifest中注册。