温习Android基础知识——《第一行代码(第三版)》读书笔记 Chapter 6 广播

第六章:全局大喇叭,详解广播机制

广播类型

标准广播与有序广播

标准广播

标准广播是一种完全异步执行的广播,在广播发出之后,所有的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 之后,几乎所有的隐式广播都不允许使用静态注册的方式来接收了。只有少数特殊的系统广播目前仍然允许时候静态注册的方式来接收。

扫描二维码关注公众号,回复: 11581131 查看本文章

注意

不要在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()方法。

猜你喜欢

转载自blog.csdn.net/qq_45254908/article/details/107453129