BroadcastRecevicer
动态广播最好在 Activity 的 onResume()
注册、onPause()
注销。
广播的两种注册方式的区别?
广播的分类和使用场景?
1,系统广播
Android
中内置了多个系统广播:只要涉及到手机的基本操作(如开机、网络状态变化、拍照等等),都会发出相应的广播。
例如:重启设备 ->Intent.ACTION_REBOOT
每个广播都有特定的Intent - Filter
(包括具体的action
),当使用系统广播时,只需要在注册广播接收者时定义相关的 action
即可,并不需要手动发送广播,当系统有相关操作时会自动进行系统广播。
2,本地广播(本地广播和全局广播的区别?)
广播的发送者和接收者都同属于一个 App。相比于全局广播,它的优势体现在:安全性高 & 效率高。
如何将全局广播设置成本地广播?
-
注册广播时将
exported
属性设置为false
,使得非本App
内部发出的此广播不被接收; -
在广播发送和接收时,增设相应
permission
,用于权限验证; -
发送广播时指定广播接收器所在的包名,此广播将只会发送到与之相匹配的且包名有效的广播接收器中。(通过
intent.setPackage(packageName)
指定包名)
最简单的办法就是直接使用LocalBroadcastManager
,怎么使用它呢?
使用方式上与自定义广播几乎相同,对于
LocalBroadcastManager
方式发送的应用内广播,只能通过LocalBroadcastManager
动态注册,不能静态注册。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
instance = LocalBroadcastManager.getInstance(this);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
myLocalBroadcast = new MyLocalBroadcast();
instance.registerReceiver(myLocalBroadcast, intentFilter);
}
class MyLocalBroadcast extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context , "本地广播" , Toast.LENGTH_SHORT).show();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
instance.unregisterReceiver(myLocalBroadcast);
}
对于不同的注册方式,广播接收器回调 OnReceive(Context context,Intent intent
)中的 context
值是不一样的:
-
对于静态注册,回调
onReceive(context, intent)
中的context
是:ReceiverRestrictedContext
; -
对于全局广播动态注册,回调
onReceive(context, intent)
中的context
是:Activity
; -
对于本地广播动态注册(
LocalBroadcastManager
方式),回调onReceive(context, intent)
中的context
是:Application
广播发送和接收的原理
-
接收者 通过
Binder
机制在AMS
注册 -
发送者 通过
Binder
机制向AMS
发送广播 -
AMS
根据发送者的IntentFilter / Permission
,在已注册的列表中,寻找合适的接收者。 -
如果找到了接收者,
AMS
将广播发送到目标接收者的消息循环的队列中 -
接收者通过消息循环拿到该广播,并回调
onReceive (...)
特别注意:广播发送者和广播接收者的执行是异步
的,发的人不关心你有没有收到,也不会关心你何时收到。
思考题:
-
LocalBroadcastReceiver
为何比BroadCastReceiver
速度快?
LocalBroadcastReceiver
是本地广播,只能在应用内使用和接收。BroadcastReceiver
是针对应用间、应用与系统间、应用内部进行通信的一种方式,利用 Binder 机制实现,支持动态和静态两种方式注册方式。LocalBroadcastReceiver
是应用内广播,利用Handler
实现,利用了IntentFilter
的match
功能,提供消息的发布与接收功能,实现应用内通信,效率和安全性比较高,仅支持动态注册。
普通广播是什么?
调用
sendBroadcast()
发送
有序广播是什么?
调用
sendOrderedBroadcast()
发送,广播接收者会按照priority
优先级从大到小进行排序,优先级相同的广播,动态注册的广播优先处理,广播接收者还能对广播进行截断和修改。
本地广播的优点?
效率更高。发送的广播不会离开我们的应用,不会泄露关键数据。其他程序无法将广播发送到我们程序内部,不会有安全漏洞。
现在 BroadcastReceiver
也不推荐使用静态注册了,8.0 之后限制了绝大部分广播只能使用动态注册。