当前位置 : 主页 > 手机开发 > android >

Android四大组件之broadcast广播详解

来源:互联网 收集:自由互联 发布时间:2023-02-01
目录 基础广播 两大类广播 广播的动态和静态注册 监听时间变化 监听系统启动案例 创建 receiver 设置权限 发送自定义广播 如何发送与接收 有序广播 基础广播 两大类广播 标准广播:异
目录
  • 基础广播
    • 两大类广播
    • 广播的动态和静态注册
    • 监听时间变化
  • 监听系统启动案例
    • 创建 receiver
    • 设置权限
  • 发送自定义广播
    • 如何发送与接收
  • 有序广播

    基础广播

    两大类广播

    标准广播:异步执行,广播发出后所有 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内容请搜索自由互联以前的文章或继续浏览下面的相关文章希望大家以后多多支持自由互联!

    上一篇:Android开发Jetpack组件LiveData使用讲解
    下一篇:没有了
    网友评论