标准广播是一种完全异步执行的广播,在广播发出之后,所有的BroadcastReceiver几乎会在同一时间收到这条广播消息,因此它们之间没有任何先后顺序可言,也就无法被截断,这种广播效率较高。
有序广播是一种同步执行的广播,在广播发出之后,同一时间只会有一个BroadcastReceiver能够收到这条广播消息,当这个BroadcastReceiver中的逻辑执行完毕后,广播才会继续传递,所以此时的BroadcastReceiver是有先后顺序的,优先级高的BroadcastReceiver就可以先收到广播消息,并且前面的BroadcastReceiver还可以截断。
隐式广播即没有具体指定发送给哪个应用程序的广播,大多数系统广播都属于隐式广播。
显式广播与隐式广播相反,是具体指定了发送给哪个应用程序的广播。
动态注册,即在代码中注册,如下列代码:
val intentFilter = IntentFilter()
intentFilter.addAction("android.intent.action.TIME_TICK")
timeChangeReceiver = TimeChangeReceiver()
registerReceiver(timeChangeReceiver,intentFilter)
//TimeChangeReceiver类的代码
inner class TimeChangeReceiver : BroadcastReceiver(){
override fun onReceive(context: Context?, intent: Intent?) {
Toast.makeText(context,"时代变了",Toast.LENGTH_SHORT).show()
}
}
注意,动态注册的BroadcastReceiver一定要记得取消注册。
override fun onDestroy() {
super.onDestroy()
unregisterReceiver(timeChangeReceiver)
}
静态注册,即在注册文件中注册:
先创建BootCompleteReceiver,
class BootCompleteReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
// This method is called when the BroadcastReceiver is receiving an Intent broadcast.
Toast.makeText(context,"开机了!!",Toast.LENGTH_SHORT).show()
}
}
此时AS会为我们自动在注册文件中我们的BroadcastReceiver,在其中插入< intent-filter >标签,并指定要接受的广播即可。
<receiver
android:name=".BootCompleteReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
动态注册的BroadcastReceiver可以自由地控制注册与注销,在灵活性方面有很大优势。但由于注册的逻辑是写在onCreate()方法中的,所以它只能在程序启动之后才能接收广播。
静态注册的BroadcastReceiver不仅可以监听到动态注册的BroadcastReceiver可以监听的广播,还能监听到程序未启动情况下动态注册的BroadcastReceiver监听不到的广播。
由于大量恶意应用利用静态注册的BroadcastReceiver的这一特点监听系统广播,在Android 8.0 之后,几乎所有的隐式广播都不允许使用静态注册的方式来接收了。只有少数特殊的系统广播目前仍然允许时候静态注册的方式来接收。
不要在onReceive()方法中添加过多的逻辑或者进行任何的耗时操作,因为BroadcastReceiver中是不允许开启线程的,当onReceive()方法运行了10s而没有结束时,程序就会崩溃。
我们借助Intent来发送广播
val intent = Intent("com.example.broadcasttest.MY_BROADCAST")
//这里调用setPackage方法指定这条广播是发生给哪个应用的
intent.setPackage(packageName)
sendBroadcast(intent)
设置好BroadcastReceiverd优先级后,就可以发送有序广播了。
val intent = Intent("com.example.broadcasttest.MY_BROADCAST")
//这里调用setPackage方法指定这条广播是发生给哪个应用的
intent.setPackage(packageName)
sendOrderedBroadcast(intent,null)
//sendOrderedBroadcast()方法接收两个参数,
//第一个参数仍然是Intent,第二个参数是一个与权限相关的字符串,这里传入null即可
如果需要截断,可在onReceive方法中调用abortBroadcasr()方法。