Android

关注公众号 jb51net

关闭
首页 > 软件编程 > Android > Android broadcast

Android四大组件之broadcast广播详解

作者:知奕奕

Android开发的四大组件分别是:活动(activity),用于表现功能;服务(service),后台运行服务,不提供界面呈现;广播接受者(Broadcast Receive),勇于接收广播;内容提供者(Content Provider),支持多个应用中存储和读取数据,相当于数据库,本篇着重介绍广播组件

基础广播

两大类广播

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

您可能感兴趣的文章:
阅读全文