android的broadcast的使用

485 阅读4分钟

1. 简介

安卓系统中的广播(Broadcast)是四大基本主件之一。 安卓系统内部也有很多地方使用了广播。通过广播来告知系统当前的状态。比如网络状态,充电状态,系统启动状态等等。当我们在写app时,可以通过监视,接受这些广播实现很多需求。

2. 广播种类

1. 按照广播范围

全局广播,内部广播。
全局广播:在系统全局都可以收到,包括其他的应用。
本地广播:只能在发送广播的应用内部可以接受,保证了安全,防止信息泄漏。

2. 按照广播注册方式

动态注册广播,静态注册广播。
动态注册:动态注册是使用代码,在程序执行时进行广播注册来接收广播信息。
静态注册:静态注册是在AndroidManifest文件中注册,在程序安装时已被注册,可在程序不运行时接收广播。

3. 按照广播种类

标准广播,有序广播。
标准广播(Normal Broadcast):完全异步的广播,所有的广播接收器几乎同时受到广播且无法截断。
有序广播(Order Broadcast):有序广播是按照接收器的优先级进行传递,可以在接收器接收以后进行阻断,防止向下进行传递。

3. 代码实现

1. 广播注册
动态注册

首先来看以下广播的动态注册:

 networkReceiver = NetworkReceiver()
 intentFilter = IntentFilter()
 intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE") //注册的是接收网络状态信息的广播
 registerReceiver(networkReceiver, intentFilter)

但是动态注册的方式有一个注意的地方就是,需要在activity的onDestory方法中对注册的广播进行解除。原因是如果注册的组件不解除的话,会有内存泄漏。解除方法如下:

override fun onDestroy() {
    super.onDestroy()
    unregisterReceiver(networkReceiver)
}
静态注册

静态注册时要在AndroidManifest.xml上进行注册。 静态注册的劣势是不能灵活的进行广播的注册和解除。一旦注册就不能解除。 静态注册的优势是可以在不运行程序的情况下接收广播信息。 静态注册方法如下, 需在写在<application>标签里面:

<receiver
    android:name=".BootReceiver"
    android:enabled="true"
    android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </receiver>

对上述的注册方法进行简单的说明。 androiod:name :需要写上广播接收器的类名,接收器的具体写法在后面进行说明。 android:enabled :是否实例化广播接收器,true则有效,false为无效不能接受广播内容。 andorid:exported :是否可以接受来自其应用外部的广播。 :intent过滤器 :接收的广播标签,可以是系统内部的,也可以是自定义的。上述的标签是系统启动完成时发送的广播标签。

2. 接收器

接收器的写法是跟广播的内容没有关系的。需要继承自BroadCastReceiver类,并重写onReceive方法。onReceive里的内容就是当接收到相应的广播时的动作。比如弹窗,或者更改UI等等。

class BootReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        Toast.makeText(context, "OS Boot Completed!", Toast.LENGTH_LONG).show()
    }
}
3. 发送广播
发送标准广播

广播发送的方法也是大体差不太多。首先看一下标准广播的发送方法。

val intent = Intent("com.example.moon")
sendBroadcast(intent)

intent实例化时传入的参数是action,这里的值需要和想要接收信息广播注册时的action需要一致。比如上面静态注册的广播的"android.intent.action.BOOT_COMPLETED"里改写成"com.example.moon"就可以了。

发送本地标准广播

上面的标准广播的发送方法是全局广播,但是为了信息安全要发送本地广播时可以使用LocalBroadcastManager来管理本地广播的接收和发送。 首先看一下本地广播的注册方式,和上面叙述的全局广播的动态这册方式差不多。

// 获得本地广播管理器
localBroadcastManager = LocalBroadcastManager.getInstance(this)

localIntentFilter = IntentFilter()
localIntentFilter.addAction("com.example.moon")

//实例化本地广播的接收器,上正常的广播接收器写法是一样的
localBroadCastReceiver = LocalBroadCastReceiver() 

// 通过本地广播管理器来注册广播
localBroadcastManager.registerReceiver(localBroadCastReceiver, localIntentFilter)

同样,不能忘了广播的解除。

override fun onDestroy() {
    super.onDestroy()
    // 本地广播的解除
    localBroadcastManager.unregisterReceiver(localBroadCastReceiver)
}

最后是发送本地广播。

val intent = Intent("com.example.moon")
localBroadcastManager.sendBroadcast(intent) // 通过本地广播管理器来发送
有序广播的发送

有序广播在注册时跟标准广播不同的地方是需要设置优先级。 动态注册时:

intentFilter.priority = 98

静态注册时:

<intent-filter priority = 98>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>

发送方法如下:

sendOrderBroadcast(intent)

当在某一个接收器进行截断,防止往下进行传递,需在接收器中写如下代码:

abortBroadcast()//截断该广播

4. 代码

github: github.com/HyejeanMOON…