文章目录

广播的种类

  • 普通广播/无序广播
    表现为广播的接收者们将不区分先后顺序,几乎同时接收广播,并且广播接收者们在接收广播时互不相干
  • 有序广播
    表现为广播的接收者们会根据一定的先后顺序,接收到广播。类似于生活中的“传话”的特性
  • 粘滞广播/粘性广播(也区分为有序和无序)
    无视,在Android 5.0已声明为过期

栗子:发送有序广播

对上一篇的栗子进行改进,增加1个按钮

<Button
android:id="@+id/btn_send_ordered_broadcast"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="发送有序广播"/>

MainActivity

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
...
private Button btnSendOrderedBroadcast;
...
private int number;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

...
btnSendOrderedBroadcast = findViewById(R.id.btn_send_ordered_broadcast);
...
btnSendOrderedBroadcast.setOnClickListener(this);
}

@Override
public void onClick(View view) {
switch (view.getId()) {
...
case R.id.btn_send_ordered_broadcast:
//准备Intent对象
Intent intent2 = new Intent();
intent2.setPackage("com.example.testapplication");
intent2.putExtra("_number", number);
number++;
intent2.setAction("CCTV1");
//接收者的权限
String receiverPermission = null;
//发送有序广播
sendOrderedBroadcast(intent2, receiverPermission);
break;
case R.id.btn_register_receiver:
if (receiver == null) {
receiver = new InnerReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("CCTV5");
filter.addAction("CCTV1");
registerReceiver(receiver, filter);
}
...
}
}

private class InnerReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
//区分广播的“频道”
String action = intent.getAction();
if ("CCTV5".equals(action)) {
String date = intent.getStringExtra("date");
Log.d("BROADCAST", "InnerReceiver->onReceive();时间:" + date);
} else if ("CCTV1".equals(action)) {
int number = intent.getIntExtra("_number", -999);
Log.d("BROADCAST", "InnerReceiver->onReceive();_number:" + number);
} else {

}
}
}
}

增加一个按钮,增加点击事件,让其发送有序广播,这次发送的频道是“CCTV1”,为了能让 InnerReceiver 也能接收“CCTV1”,我们在动态注册 InnerReceiver 时,除了​​filter.addAction("CCTV5");​​也增加

filter.addAction("CCTV1");

然后在接收到广播时,对“频道”进行区分,再进行不同的处理

String action = intent.getAction();

与此同时,我们还有 CustomReceiver 和 CustomReceiver2 ,也进行同样的“频道”区分操作

CustomReceiver

public class CustomReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//区分广播的“频道”
String action = intent.getAction();
if ("CCTV5".equals(action)) {
String date = intent.getStringExtra("date");
Log.d("BROADCAST", "CustomReceiver->onReceive();时间:" + date);
} else if ("CCTV1".equals(action)) {
int number = intent.getIntExtra("_number", -999);
Log.d("BROADCAST", "CustomReceiver->onReceive();_number:" + number);
} else {
}
}
}

CustomReceiver2

public class CustomReceiver2 extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//区分广播的“频道”
String action = intent.getAction();
if ("CCTV5".equals(action)) {
String date = intent.getStringExtra("date");
Log.d("BROADCAST", "CustomReceiver2->onReceive();时间:" + date);
} else if ("CCTV1".equals(action)) {
int number = intent.getIntExtra("_number", -999);
Log.d("BROADCAST", "CustomReceiver2->onReceive();_number:" + number);
} else {
}
}
}

在AndroidManifest中进行注册

<receiver android:name=".CustomReceiver">
<intent-filter>
<action android:name="CCTV1"/>
<action android:name="CCTV5"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</receiver>

<receiver android:name=".CustomReceiver2">
<intent-filter>
<action android:name="CCTV1"/>
<action android:name="CCTV5"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</receiver>

运行程序

点击发送普通广播

D/BROADCAST: Mainctivity->onClick();时间:1523513945123
D/BROADCAST: CustomReceiver->onReceive();时间:1523513945123
D/BROADCAST: CustomReceiver2->onReceive();时间:1523513945123

点击发送有序广播

D/BROADCAST: CustomReceiver->onReceive();_number:0
D/BROADCAST: CustomReceiver2->onReceive();_number:0

再次点击发送有序广播

D/BROADCAST: CustomReceiver->onReceive();_number:1
D/BROADCAST: CustomReceiver2->onReceive();_number:1

点击注册内部接收者,再点击发送有序广播

D/BROADCAST: InnerReceiver->onReceive();_number:2
D/BROADCAST: CustomReceiver->onReceive();_number:2
D/BROADCAST: CustomReceiver2->onReceive();_number:2

广播的接收者们的优先级

  1. 根据注册广播时,IntentFilter 的​​priority​​属性决定,该属性的值是 int 类型的数值,数值越大,则优先级越高,即更优先接收到广播
  2. 当多个广播接收者的​​priority​​属性值相同时,动态注册的广播接收者优先级更高
  3. 当根据以上 2 条无法确定优先级时,将根据注册的先后顺序进行区分,先注册的优先级更高
  4. 如果在不同的应用程序中,都使用了相同的注册方式,且 priority 属性值相同
    如果是使用的动态注册,可以直接区分出执行注册的先后顺序
    如果是使用的静态注册,则根据项目的 package 属性值,按字典排序法进行区分

栗子

现有 3 个广播接收者

【达内课程】BroadcastReceiver(中)_broadcastreceiver

代码类似,以 HighReceiver 为例

public class HighReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//区分广播的“频道”
String action = intent.getAction();
if("CCTV5".equals(action)){
String date = intent.getStringExtra("date");
Log.d("BROADCAST","HighReceiver->onReceive();时间:"+date);
}else if("CCTV1".equals(action)){
int number = intent.getIntExtra("_number",-999);
Log.d("BROADCAST","HighReceiver->onReceive();_number:"+number);
}else{

}
}
}

都需要在AndroidManifest中注册

<receiver android:name=".HighReceiver">
<intent-filter>
<action android:name="CCTV1"/>
<action android:name="CCTV5"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</receiver>

布局和上个栗子相同
【达内课程】BroadcastReceiver(中)_android_02
除了上面的 HighReceiver、MidReceiver 和 LowReceiver 外,我们在 MainActivity 中再定义 3 个内部接收者 InnerHighReceiver、InnerMidReceiver 和 InnerLowReceiver

MainActivity进行改进

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button btnSend;
private Button btnResiger;
private Button btnUnregister;
private Button btnSendOrderedBroadcast;
private InnerHighReceiver highReceiver;
private InnerMidReceiver midReceiver;
private InnerLowReceiver lowReceiver;
private int number;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

btnSend = findViewById(R.id.btn_send);
btnResiger = findViewById(R.id.btn_register_receiver);
btnUnregister = findViewById(R.id.btn_unregister_receiver);
btnSendOrderedBroadcast = findViewById(R.id.btn_send_ordered_broadcast);
btnSend.setOnClickListener(this);
btnResiger.setOnClickListener(this);
btnUnregister.setOnClickListener(this);
btnSendOrderedBroadcast.setOnClickListener(this);
}

@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btn_send:
long date = System.currentTimeMillis();
Intent intent = new Intent();
intent.setPackage("com.example.testapplication");
intent.setAction("CCTV5");
intent.putExtra("date", "" + date);
Log.d("BROADCAST", "Mainctivity->onClick();时间:" + date);
sendBroadcast(intent);
break;
case R.id.btn_send_ordered_broadcast:
//准备Intent对象
Intent intent2 = new Intent();
intent2.setPackage("com.example.testapplication");
intent2.putExtra("_number", number);
number++;
intent2.setAction("CCTV1");
//接收者的权限
String receiverPermission = null;
//发送有序广播
sendOrderedBroadcast(intent2, receiverPermission);
break;
case R.id.btn_register_receiver:
if (highReceiver == null) {
highReceiver = new InnerHighReceiver();
IntentFilter hignFilter = new IntentFilter();
hignFilter.addAction("CCTV5");
hignFilter.addAction("CCTV1");
registerReceiver(highReceiver, hignFilter);
}
if (midReceiver == null) {
midReceiver = new InnerMidReceiver();
IntentFilter midFilter = new IntentFilter();
midFilter.addAction("CCTV5");
midFilter.addAction("CCTV1");
registerReceiver(midReceiver, midFilter);
}
if (lowReceiver == null) {
lowReceiver = new InnerLowReceiver();
IntentFilter lowFilter = new IntentFilter();
lowFilter.addAction("CCTV5");
lowFilter.addAction("CCTV1");
registerReceiver(lowReceiver, lowFilter);
}
break;
case R.id.btn_unregister_receiver:
if (highReceiver != null) {
unregisterReceiver(highReceiver);
highReceiver = null;
}
if (midReceiver != null) {
unregisterReceiver(midReceiver);
midReceiver = null;
}
if (lowReceiver != null) {
unregisterReceiver(lowReceiver);
lowReceiver = null;
}
break;
}
}

private class InnerHighReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
//区分广播的“频道”
String action = intent.getAction();
if ("CCTV5".equals(action)) {
String date = intent.getStringExtra("date");
Log.d("BROADCAST", "InnerHighReceiver->onReceive();时间:" + date);
} else if ("CCTV1".equals(action)) {
int number = intent.getIntExtra("_number", -999);
Log.d("BROADCAST", "InnerHighReceiver->onReceive();_number:" + number);
} else {

}
}
}
private class InnerMidReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
//区分广播的“频道”
String action = intent.getAction();
if ("CCTV5".equals(action)) {
String date = intent.getStringExtra("date");
Log.d("BROADCAST", "InnerMidReceiver->onReceive();时间:" + date);
} else if ("CCTV1".equals(action)) {
int number = intent.getIntExtra("_number", -999);
Log.d("BROADCAST", "InnerMidReceiver->onReceive();_number:" + number);
} else {

}
}
}
private class InnerLowReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
//区分广播的“频道”
String action = intent.getAction();
if ("CCTV5".equals(action)) {
String date = intent.getStringExtra("date");
Log.d("BROADCAST", "InnerLowReceiver->onReceive();时间:" + date);
} else if ("CCTV1".equals(action)) {
int number = intent.getIntExtra("_number", -999);
Log.d("BROADCAST", "InnerLowReceiver->onReceive();_number:" + number);
} else {

}
}
}
}

在不指定优先级的情况下,先点击“注册内部接收者”,然后点击发送“有序广播”
观察日志

D/BROADCAST: InnerHighReceiver->onReceive();_number:0
D/BROADCAST: InnerMidReceiver->onReceive();_number:0
D/BROADCAST: InnerLowReceiver->onReceive();_number:0
D/BROADCAST: HignReceiver->onReceive();_number:0
D/BROADCAST: MidReceiver->onReceive();_number:0
D/BROADCAST: LowReceiver->onReceive();_number:0

我们发现内部接收者会优先收到广播,下面我们手动设置​​priority​​属性

先设置内部类

@Override
public void onClick(View view) {
switch (view.getId()) {
...
case R.id.btn_register_receiver:
if (highReceiver == null) {
highReceiver = new InnerHighReceiver();
IntentFilter hignFilter = new IntentFilter();
hignFilter.setPriority(100);
hignFilter.addAction("CCTV5");
hignFilter.addAction("CCTV1");
registerReceiver(highReceiver, hignFilter);
}
if (midReceiver == null) {
midReceiver = new InnerMidReceiver();
IntentFilter midFilter = new IntentFilter();
midFilter.setPriority(500);
midFilter.addAction("CCTV5");
midFilter.addAction("CCTV1");
registerReceiver(midReceiver, midFilter);
}
if (lowReceiver == null) {
lowReceiver = new InnerLowReceiver();
IntentFilter lowFilter = new IntentFilter();
lowFilter.setPriority(900);
lowFilter.addAction("CCTV5");
lowFilter.addAction("CCTV1");
registerReceiver(lowReceiver, lowFilter);
}
break;
...
}
}

再设置外部类

<receiver android:name=".HighReceiver">
<intent-filter>
<action android:name="CCTV1"/>
<action android:name="CCTV5"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</receiver>
<receiver android:name=".MidReceiver">
<intent-filter android:priority="1000">
<action android:name="CCTV1"/>
<action android:name="CCTV5"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</receiver>
<receiver android:name=".LowReceiver">
<intent-filter android:priority="5000">
<action android:name="CCTV1"/>
<action android:name="CCTV5"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</receiver>

同样的先点击“注册内部接收者”,然后点击发送“有序广播”
观察日志

D/BROADCAST: LowReceiver->onReceive();_number:0
D/BROADCAST: MidReceiver->onReceive();_number:0
D/BROADCAST: InnerLowReceiver->onReceive();_number:0
D/BROADCAST: InnerMidReceiver->onReceive();_number:0
D/BROADCAST: InnerHighReceiver->onReceive();_number:0
D/BROADCAST: HighReceiver->onReceive();_number:0