广播机制
Android中的广播机制更加灵活:
因为Android中的每个应用都可以堆自己感兴趣的广播进行注册
这样该程序就只会收到自己关心的广播内容
这些广播可能是来自系统的,也可能是来自其他应用的
发送广播是通过intent
接受广播是通过BroadcastReveiver
广播分成两类:
- 标准广播:完全异步执行,在广播发出之后,几乎所有broadcastReceiver会在同一时间收到这条广播消息,因此他们之间没有任何先后顺序可言,这种广播的效率比较高,但同时他也是无法被截断的
- 有序广播:同步执行,广播发出之后,同样一时间只会有一个BroadcastReceiver能够接收到这条广播消息,当BroadcastReceiver中的逻辑执行完了之后,广播才会继续传递,此时的BroadcastReceiver是有先后顺序的,优先级高的会先收到广播消息,并且前面的BroadcastReceiver可以截断消息,这样后面的BroadcastReceiver就无法接收到广播消息了
接收系统广播
我们可以根据自己感兴趣的广播,自由的注册BroadcastReceiver这样相应的广播发出时候,就会有相应的BroadcastReceiver能够接收广播,并且可以在内部进行逻辑处理
注册BroadcastReceiver的方式
- 在代码中动态注册
- 在AdnroidManifest.xml中静态注册
动态广播
实践出真知
class MainActivity : AppCompatActivity() {
lateinit var timeChangeReceiver:TimeChangeReceiver
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
/*intent和intentFilter的区别
后者比前者多了个筛选作用
筛选条件:
action、data和category*/
val intentFilter=IntentFilter()//定义一个有过滤器的意图
intentFilter.addAction("android.intent.action.TIME_TICK")
//给意图添加一个筛选条件(筛选出Action是android.intent.action.TIME_TICK的意图)
timeChangeReceiver=TimeChangeReceiver()//实例化一个时间改变广播接收器
registerReceiver(timeChangeReceiver,intentFilter)//注册一个广播接收器timeChangeReveiver来监听intentFilter这个意图
}
override fun onDestroy() {
super.onDestroy()
//当这个活动销毁的时候就把接收器取消注册(一定要取消)
unregisterReceiver(timeChangeReceiver)
}
inner class TimeChangeReceiver:BroadcastReceiver(){
//定义一个接收器继承自BroadcastReceiver,
override fun onReceive(context: Context, intent: Intent) {
//当接收到一个消息就Toast一段话
Toast.makeText(context,"Time Changed",Toast.LENGTH_LONG).show()
}
}
}
注册了注册一个广播接收器timeChangeReveiver来监听有这个动作(android.intent.action.TIME_TICK)的intentFilter这个意图,一旦时间过了一分钟广播接收器就会收到时间过了一分钟这个广播,然后Toast一句话
静态广播
- 动态注册的广播接收器虽然可以自由的控制注册和注销,灵活性有优势,但是他只有在程序启动后才能接收广播.
- 那么我们就可以用静态注册来在程序未启动的时候监听系统广播,但是这种方式给了恶意软件很大的操作空间,所以Android系统几乎每个版本都在削减静态注册的功能
- 在Android8.0之后所有的隐式广播都不允许用讲堂注册的方式来接收了,隐式广播指的是那些没有具体指定发送给哪个应用程序的广播,大多数系统广播属于隐式广播,但是还有小部分的允许静态注册的方式接收小部分见官网
实践出真知
新建一个Other->BroadcastReceiver
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,"Boot Complete",Toast.LENGTH_LONG).show()
/*但是注意在onReceive中不要使用太复杂的逻辑因为BroadcastReceiver中不允许开启线程
当onReceive运行太久而没结束程序就会出现错误*/