厦门住房建设局网站首页/深圳新闻今日最新
参考:android BroadcastReceiver 介绍
【Android 一般进阶】动态广播注册注销时机
APP内部广播优先使用:LocalBroadcastManager本地广播
注册推荐在activity生命周期的oncreate
取消注册在activity生命周期的ondestroy,注意按返回键(onKeyDown或者onBackPressed)也需要取消注册。
BroadcastReceiver作为Android四大组件之一,不像Activity,没有可显示的界面。
BroadcastReceiver包括两个概念,广播发送者和广播接收者(Receiver),
Android广播的分类:
1、 普通广播:这种广播可以依次传递给各个处理器去处理
2、 有序广播:这种广播在处理器端的处理顺序是按照处理器的不同优先级来区分的,高优先级的处理器会优先截获这个消息,并且可以将这个消息删除
3、 粘性消息:粘性消息在发送后就一直存在于系统的消息容器里面,等待对应的处理器去处理,如果暂时没有处理器处理这个消息则一直在消息容器里面处于等待状态,粘性广播的Receiver如果被销毁,那么下次重建时会自动接收到消息数据。
注意:普通广播和粘性广播不会被截获,而有序广播是可以被截获的。
在Android系统粘性广播一般用来确保重要的状态改变后的信息被持久保存,并且能随时广播给新的广播接收器,比如电源的改变,因为耗电需要一个过程,前一个过程必须提前得到,否则可能遇到下次刚好接收到的广播后系统自动关机了,随之而来的是kill行为,所以对某些未处理完的任务来说,后果很严重。
发送粘性广播需要权限(这里的权限是保存信息的权限和由系统发送未处理的广播的权限)
<uses-permission android:name="android.permission.BROADCAST_STICKY" />
这里的广播实际就是指Intent,程序可以自己发送广播自己接收,也可以接受系统或其他应用的广播或是发送广播给其他应用程序。
发送者可以通过类似Context.sendBroadcast(intent)接口发送广播,
接收者通过Context.registerReceiver()动态注册
@Overrideprotected void onResume(){super.onResume();//实例化BroadcastReceiver子类 & IntentFiltermBroadcastReceiver = new MyBroadcastReceiver();IntentFilter intentFilter = new IntentFilter();//设置接收广播的类型intentFilter.addAction(android.net.conn.CONNECTIVITY_CHANGE);//调用Context的registerReceiver()方法进行动态注册registerReceiver(mBroadcastReceiver, intentFilter);}//注册广播后,要在相应位置记得销毁广播
//即在onPause() 中unregisterReceiver(mBroadcastReceiver)
//当此Activity实例化时,会动态将MyBroadcastReceiver注册到系统中
//当此Activity销毁时,动态注册的MyBroadcastReceiver将不再接收到相应的广播。@Overrideprotected void onPause() {super.onPause();//销毁在onResume()方法中的广播unregisterReceiver(mBroadcastReceiver);}
}public class MyBroadcastReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {}}
或 在AndroidManifest.xml文件中通过标签静态注册,
<receiver android:name="MyReceiver"><intent-filter><action android:name="android.intent.action.BOOT_COMPLETED"></action></intent-filter></receiver>
注册完成后,当发送者发送某个广播时系统会将发送的广播(Intent)与系统中所有注册的符合条件的接收者(Receiver)
的IntentFilter进行匹配,若匹配成功则执行相应接收者的onReceive函数。
注册和取消注册广播放在了OnResume和OnPause函数中可以有效的节省系统消耗。
如果希望广播一直运行中可以在Activity的OnCreate函数中注册,在OnDestrory函数中取消注册。
生命周期
BroadcastReceiver在onReceive函数执行结束后即表示生命周期结束,
所以不适合在onReceive中做绑定服务操作,结束后若某个进程只含有该BroadcastReceiver,
则优先级将降低可能被系统回收,所以BroadcastReceiver中不适合做一些异步操作,
如新建线程下载数据,BroadcastReceiver结束后可能在异步操作完成前进程已经被系统kill。
同时由于ANR限制BroadcastReceiver的onReceive函数必须在10秒内完成,
而且onReceive默认会在主线程中执行,所以BroadcastReceiver中不适合做一些耗时操作,
对于耗时操作需要交给service处理,比如网络或数据库耗时操作、对话框的显示(因为现实时间可能超时,用Notification代替)。
普通广播(Normal Broadcast):
一,优缺点:和有序广播的优缺点相反!
二,发送广播的方法:sendBroadcast()
有序广播(Ordered Broadcast):
一,优缺点
优点:1,按优先级的不同,优先Receiver可对数据进行处理,并传给下一个Receiver
2,通过abortBroadcast可终止广播的传播
缺点:效率低
二,发送广播的方法:sendOrderedBroadcast()
三,优先接收到Broadcast的Receiver可通过setResultExtras(Bundle)方法将处理结果存入Broadcast中,
下一个Receiver 通过 Bundle bundle=getResultExtras(true)方法获取上一个Receiver传来的数据
全局广播和本地广播
广播还可以分为 全局广播和本地广播
全局广播:发出去的广播可以被任何应用程序接收到,也可以接受来自任何应用程序的广播
本地广播:使用LocalBroadcaseManager对广播进行管理,
LocalBroadcastManager本地广播
接收广播
private LocalBroadcastManager mLocalBroadcastManager;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_exception);mLocalBroadcastManager = LocalBroadcastManager.getInstance(this);IntentFilter filter=new IntentFilter(); filter.addAction("com.example.chainOfResponsibility"); manager.registerReceiver(new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context, "onReceive", Toast.LENGTH_SHORT).show(); } }, filter); }
通过LocalBroadcastManager 的getInstance()方法得到了它的一个实例,
然后在注册广播接收器的时候调用的是LocalBroadcastManager的registerReceiver()方法。
取消接收广播:
@Overrideprotected void onDestroy() {super.onDestroy();mLocalBroadcastManager.unregisterReceiver(mBroadcastReceiver);}
取消接收广播的时候调用的是LocalBroadcastManager 的unregisterReceiver()方法。
发送广播
LocalBroadcastManager mLocalBroadcastManager=LocalBroadcastManager.getInstance(context); Intent intent=new Intent();
intent.putExtra("type", type);
intent.putExtra("progress", progress);
intent.setAction("com.example.chainOfResponsibility"); mLocalBroadcastManager.sendBroadcast(intent);
发送广播的时候调用的是LocalBroadcastManager 的sendBroadcast()方法。
本地广播和全局广播的一大区别
本地广播不能通过静态的方式来注册接受。
其实这也可以理解,因为静态注册是要是让程序在未启动的情况下也能接受广播,发送本地广播的时候程序可定启动了。
使用本地广播的几点优势:
- 可以明确地知道正在发送的广播不会离开我们的程序,因此不需要担心机密数据泄漏的问题。
- 其他的程序无法将广播发送到我们程序的内部,因此不需要担心会有安全漏洞的隐患。
- 发送本地广播比起发送系统全局广播将会更加高效。
Sticky Broadcast粘性广播
如果发送者发送了某个广播,而接收者在这个广播发送后才注册自己的Receiver,
这时接收者便无法接收到刚才的广播,为此Android引入了StickyBroadcast,
在广播发送结束后会保存刚刚发送的广播(Intent),这样当接收者注册完Receiver后就可以继续使用刚才的广播。
如果在接收者注册完成前发送了多条相同Action的粘性广播,注册完成后只会收到一条该Action的广播,
并且消息内容是最后一次广播内容。系统网络状态的改变发送的广播就是粘性广播。
粘性广播通过Context的sendStickyBroadcast(Intent)接口发送,需要添加权限
<uses-permission android:name="android.permission.BROADCAST_STICKY"/>
也可以通过Context的removeStickyBroadcast(Intent intent)接口移除缓存的粘性广播。