Android四大组件之broadcast广播详解
作者:知奕奕
基础广播
两大类广播
标准广播:异步执行,广播发出后所有 receiver 同时接收,无先后顺序,无法被截断;
有序广播:同步执行,类似于中间件,每个 receiver 拦截广播后有权将其下放到下一个 receiver 或者直接截断;
广播的动态和静态注册
动态注册:写在代码里面的监听事件;
静态注册:写在 manifest.xml 里面的监听;
目前,由于安卓为了维护用户系统安全,故所有的隐式广播均不允许静态注册
监听时间变化
在主 activity 里面编写如下代码,实现每隔一分钟监听一次时间变化并 toast 弹出信息;
package com.zhiyiyi.listviewdemo import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.content.IntentFilter import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.widget.Toast import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.StaggeredGridLayoutManager import com.zhiyiyi.listviewdemo.R import com.zhiyiyi.listviewdemo.RecyclerAdapter import kotlinx.android.synthetic.main.activity_main.* import java.util.* import kotlin.collections.ArrayList class MainActivity : AppCompatActivity() { // 延迟初始化监听器 lateinit var timeChangeReceiver: TimeChangeReceiver override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // 设置过滤器 val intentFilter = IntentFilter() // 过滤的广播类型为TIME_TICK intentFilter.addAction("android.intent.action.TIME_TICK") // 实例化监听器 timeChangeReceiver = TimeChangeReceiver() // 注册广播监听器 registerReceiver(timeChangeReceiver, intentFilter) } override fun onDestroy() { super.onDestroy() // 销毁activity的时候别忘了注销广播监听器 unregisterReceiver(timeChangeReceiver) } // 使用内部类动态注册广播监听器 inner class TimeChangeReceiver : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { Toast.makeText(context, "time changed", Toast.LENGTH_SHORT).show() } } }
监听系统启动案例
创建 receiver
我们可以右键点击项目,来使用官方提供的模板创建 broadcastreceiver;
这种方式创建后,会自动在 manifest 文件内注册该外部 receiver,否则会需要我们手动来进行注册,十分不方便;
我们据此创建 BootReceiver.kt
编写代码如下,依旧是接收到广播弹出 toast
package com.zhiyiyi.listviewdemo import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.widget.Toast class BootReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { Toast.makeText(context, "boot start", Toast.LENGTH_SHORT).show() } }
设置权限
为了监听系统启动广播,我们需要静态注册(该广播事实上是一个隐式广播,但因为安全隐患小,安卓并没有禁止其静态注册!)
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <!-- 在这里注册权限 --> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> <application android:allowBackup="true" android:dataExtractionRules="@xml/data_extraction_rules" android:fullBackupContent="@xml/backup_rules" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.ListViewDemo" tools:targetApi="31"> <receiver android:name=".BootReceiver" android:enabled="true" android:exported="true"> <!-- 设置过滤器 --> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED"/> </intent-filter> </receiver> ... </application> </manifest>
发送自定义广播
如何发送与接收
新建广播监听器文件:CustomReceiver.kt
编写监听到后反应
class CustomReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { Toast.makeText(context, "custom receiver", Toast.LENGTH_SHORT).show() } }
在 manifest 中在对应监听器下设置过滤器
<receiver android:name=".BootReceiver" android:enabled="true" android:exported="true"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> </intent-filter> </receiver>
主 activity 中设置点击按钮发送广播,此时自定义监听器监听到信息,弹出 toast
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) broad_btn.setOnClickListener { val intent = Intent("receiver.MYCUSTOM") Log.d(TAG, "onClick: fuck") intent.setPackage(packageName) sendBroadcast(intent) } } }
解释一下 setPackage
因为所有隐式广播都无法使用静态注册,而我们使用的自定义广播全部都是隐式广播;
我们只有使用 setPackage 将自身变成显示广播,才能推送到隐式广播接收器;
有序广播
监听器在 manifest 中注册时,在过滤器后加上出现设置权限值;
权限越高的越早能截获信息;
<intent-filter android:priority="100">
主 activity 使用 sendOrderedBroadcast 来发送有序列的广播;
第一个参数是 intent,第二个参数我们一般都填 null
sendOrderedBroadcast(intent,null)
自定义广播的末尾可以加上 abortBroadcast 可以销毁该广播,即广播终止位置到此为止,后面的优先级较低的都无监听器法接受到了
class CustomReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { ... // 拦截并销毁该广播 abortBroadcast() } }
到此这篇关于Android四大组件之broadcast广播详解的文章就介绍到这了,更多相关Android broadcast内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!