广播接收者
概念
Android中的广播机制比我们日常生活中接触的广播更加灵活,Android中的每个应用程序都可以对自己感兴趣的广播进行注册,这样做的好处是我只接收我需要的广播,其他广播直接忽略。这些广播可以是来自于系统也可以是用户自定义的广播。
广播的类型:
标准广播:一套完全异步执行的广播,在广播发出去之后,所有的广播接收者几乎同时收到广播,接收者之间没有先后顺序的优先级之分。特点的效率高。有序广播:同步执行的广播,同一时刻只能有一个广播接收者收到广播,当当前广播接收者执行完自己的逻辑之后,广播才会继续向下传递。优先级越高的广播接受者越先收到广播,同时先收到的广播接受者可以截断广播,阻止广播继续向下传递。
广播的优先级设定:-1000-1000
有些情况下,某些广播接受者必须要接收到广播(防止其他优先级高的接收者阻拦),可以设置为结果接收者(resultReceive):表示所有广播接收者都接收到广播之后,它才接收,并且一定会接收
定义方式:
定义一个类继承BroadcastReceiver,重写onReceive()方法即可,在该方法内部不要实现过多的逻辑或耗时操作,因为广播不能开启子线程。在清单文件中配置该类,指定接收的广播种类广播是通过intent发送的,intent中会携带一个action,系统会在所有清单文件中寻找,看哪一个广播接收者的intent-filter和广播中的intent是匹配的,那么这个广播接收者就会收到这条广播
广播接收者所在进程即便没有启动,广播发送出来时,系统也会启动这个进程,然后把广播交给广播接收者
一个广播接收者可以接受多种广播,定义多个action即可
广播接收者注册:
清单文件注册:广播接收者永远生效,除非卸载应用,或者手动停止进程。设置接收开启启动的广播
<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
权限
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
使用代码注册:需要广播接收者生效时,注册它,不需要时,一定要反注册它,反注册之后,广播接收者就失效了。
private IntentFilter mIntentFilter;
private MyReceiver mReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mIntentFilter = new IntentFilter();
mIntentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
mReceiver = new MyReceiver();
registerReceiver(mReceiver, mIntentFilter);
}
class myReceive extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
//实现逻辑
}
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(mReceiver);
}
特殊广播接收者,必须代码注册:屏幕开关、电量改变等
在程序中动态注册广播必须要在代码中取消注册,一般情况下在Activity的onDestory()方法中取消注册
静态注册广播需要在Mainfest中进行配置,可以收到程序在没有启动状态下的广播接收
当一条广播被发送出来时,系统是在所有清单文件中遍历,通过匹配意图过滤器找到能接收这条广播的广播接收者
发送自定义广播:
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//处理收到广播的逻辑
}
}
<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.example.broadcasttest.MY_BROADCAST"/>
</intent-filter>
</receiver>
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("com.example.broadcasttest.MY_BROADCAST");
sendBroadcast(intent);
}
});
}
本地广播
使用LocalBroadcastManager对广播进行管理,并提供发送和注册广播接收器的方法。本地广播无法通过静态方式注册,因为静态注册就是为了让程序在未启动的时候也能收到广播,而发生本地广播时,我们的程序是肯定启动了。
本地广播的优点:
可以明确地知道正在发送的广播不会离开我们的程序,因此不必担心机密数据泄露
其他的程序无法将广播发送到我们程序的内部,因此不需要担心会有安全问题
发送本地广播比发送系统全局广播将会更加高效
public class MainActivity extends AppCompatActivity {
private IntentFilter intentFilter;
private LocalReceiver localReceiver;
private LocalBroadcastManager localBroadcastManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
localBroadcastManager = LocalBroadcastManager.getInstance(this); // 获取实例
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("com.example.broadcasttest.LOCAL_BROADCAST");
localBroadcastManager.sendBroadcast(intent); // 发送本地广播
}
});
intentFilter = new IntentFilter();
intentFilter.addAction("com.example.broadcasttest.LOCAL_BROADCAST");
localReceiver = new LocalReceiver();
localBroadcastManager.registerReceiver(localReceiver, intentFilter); // 注册本地广播监听器
}
@Override
protected void onDestroy() {
super.onDestroy();
localBroadcastManager.unregisterReceiver(localReceiver);
}
class LocalReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "received local broadcast", Toast.LENGTH_SHORT).show();
}
}
}