-
基础概念
广播机制是Android系统中很重要的通信机制,它可以实现程序内部和不同应用之间传递消息。发出广播和接收广播是两个不同的动作,我们可以将其想象成电视广播信号的发出和接收。
-
发出广播和接收广播
在应用开发时,多数情形需要注册接收器(BroadcastReceiver),响应广播,从而来启动某个功能。如果需要的话,应用也可以主动发出广播。Android系统也会发出广播,我们称之为系统广播,应用程序发出的广播称之为自定义广播。一个应用发出广播的数量和可接收广播的数量都没有限制。
发送广播的方法位于Content类中,具体描述如下:
void sendBroadcast(Intent intent,String receiverPermission) | 发送广播,接收广播时需要相应权限 |
void sendBroadcast(Intent intent) | 发送广播,不设权限 |
void sendOrderedBroadcast(Intent intent,String receiverPermission) | 发送有序广播,接收广播时需要相应权限 |
接收广播需要自定义广播接收器,继承BroadcastReceiver类。
需要注意的是,和Activity与Service不同,BroadcastReceiver的生命周期很短。当系统或其他程序发送广播时,Android系统检查所有已安装的应用程序,筛选配置文件有没有匹配的action。如果存在对应的广播接收器,并且有权限接收,那么就创建BroadcastReceiver对象,然后执行onReceiver方法。方法执行完成时,销毁BroadcastReceiver对象,所以说BroadcastReceiver生命周期短。 这就会引出一个问题,由于BroadcastReceiver生命周期很短,所以在onReceiver方法中不能执行比较耗时的操作(一般不能超过10s),否则会弹出ANR(应用无响应)对话框。如果需要完成比较耗时的操作,可以启动Service组件,让Service来完成复杂的操作。同时onReceiver方法中也不能创建子线程,因为父线程被杀死后,它的子线程也会被杀死,这是很不安全的做法。
-
广播的分类与权限
Android系统中广播可以分为普通广播(无序广播)和有序广播,他们的发送方式和特效都有较大的差别。从发送广播的方法上就有区别,普通广播使用sendBroadcast方法发送,有序广播使用sendOrderedBroadcast方法发送。
普通广播对于接收器来说是无序的、没有优先级的,每个接收器都无需等待就可以接收到广播,接收器之间相互没有影响,因此广播的效率较高。这种广播无法被终止,即无法阻止其他接收器的接收动作。
有序广播对于接收器来说是有序的、有优先级区分的。广播先送到优先级高的接收器,然后送到优先级低的接收器,而且优先级高的接收器可以终止广播发送给优先级低的接收器。广播接收器的优先级可以在注册时设置,使用intent-filter类的属性android:priority,取值范围是-1000-1000,数值越大优先级越高。终止广播使用abortBroadcast方法。
广播的权限管理主要用来解决两个问题:
1、何种接收器有权接收广播,通过配置 users-permission实现
2、何种广播有权向接收器发送广播,通过设置receiver的android:permission属性实现
无论普通广播还是有序广播,在发出时都可以设定接收权限。拥有接收权限的接收器才可以响应广播。这里说的“权限”实际上就是一个字符串,接收器需要明确配置permission属性,拥有该权限就可以接收广播。
发送自定义广播:
public void sendBS(View view){
Intent broadIntent=new Intent("my.START");
sendBroadcast(broadIntent);
}
注册接收器:
广播接收器的注册方式分为静态注册和代码动态注册,下面是静态注册的代码
<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="my.START"></action>
</intent-filter>
</receiver>
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// TODO: This method is called when the BroadcastReceiver is receiving
// an Intent broadcast.
Toast.makeText(context, "Intent Detected", Toast.LENGTH_SHORT).show();
}
}
下面是动态注册广播接收器
BroadcastAvtivity.class
Button bt1,bt2,bt3;
BroadcastReceiver br1,br2,br3;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_broadcast);
bt1=(Button)findViewById(R.id.button1);
bt2=(Button)findViewById(R.id.button2);
bt3=(Button)findViewById(R.id.button3);
bt1.setOnClickListener(this);
bt2.setOnClickListener(this);
bt3.setOnClickListener(this);
br1=new MyReceiver1();
br2=new MyReceiver2();
br3=new MyReceiver3();
}
//set click action
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.button1:
sendBr();
break;
case R.id.button2:
regBr();
break;
case R.id.button3:
unRegBr();
break;
}
}
//unregister BroadcastReceiver
private void unRegBr(){
unregisterReceiver(br1);
unregisterReceiver(br2);
unregisterReceiver(br3);
}
//register BroadcastReceiver
private void regBr(){
IntentFilter filter=new IntentFilter();
filter.addAction("my.br.ACTION");
registerReceiver(br1,filter);
registerReceiver(br2,filter);
registerReceiver(br3,filter);
}
//send broadcast
private void sendBr(){
Intent intent=new Intent("my.br.ACTION");
intent.putExtra("msg","0000");
sendBroadcast(intent);
}
下篇将继续探讨Android系统中的广播机制