日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學(xué)無(wú)先后,達(dá)者為師

網(wǎng)站首頁(yè) 編程語(yǔ)言 正文

Android四大組件之broadcast廣播詳解_Android

作者:知奕奕 ? 更新時(shí)間: 2022-11-21 編程語(yǔ)言

基礎(chǔ)廣播

兩大類廣播

標(biāo)準(zhǔn)廣播:異步執(zhí)行,廣播發(fā)出后所有 receiver 同時(shí)接收,無(wú)先后順序,無(wú)法被截?cái)啵?/p>

有序廣播:同步執(zhí)行,類似于中間件,每個(gè) receiver 攔截廣播后有權(quán)將其下放到下一個(gè) receiver 或者直接截?cái)啵?/p>

廣播的動(dòng)態(tài)和靜態(tài)注冊(cè)

動(dòng)態(tài)注冊(cè):寫在代碼里面的監(jiān)聽(tīng)事件;

靜態(tài)注冊(cè):寫在 manifest.xml 里面的監(jiān)聽(tīng);

目前,由于安卓為了維護(hù)用戶系統(tǒng)安全,故所有的隱式廣播均不允許靜態(tài)注冊(cè)

監(jiān)聽(tīng)時(shí)間變化

在主 activity 里面編寫如下代碼,實(shí)現(xiàn)每隔一分鐘監(jiān)聽(tīng)一次時(shí)間變化并 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() {
    // 延遲初始化監(jiān)聽(tīng)器
    lateinit var timeChangeReceiver: TimeChangeReceiver
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        // 設(shè)置過(guò)濾器
        val intentFilter = IntentFilter()
        // 過(guò)濾的廣播類型為TIME_TICK
        intentFilter.addAction("android.intent.action.TIME_TICK")
        // 實(shí)例化監(jiān)聽(tīng)器
        timeChangeReceiver = TimeChangeReceiver()
        // 注冊(cè)廣播監(jiān)聽(tīng)器
        registerReceiver(timeChangeReceiver, intentFilter)
    }
    override fun onDestroy() {
        super.onDestroy()
        // 銷毀activity的時(shí)候別忘了注銷廣播監(jiān)聽(tīng)器
        unregisterReceiver(timeChangeReceiver)
    }
    // 使用內(nèi)部類動(dòng)態(tài)注冊(cè)廣播監(jiān)聽(tīng)器
    inner class TimeChangeReceiver : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            Toast.makeText(context, "time changed", Toast.LENGTH_SHORT).show()
        }
    }
}

監(jiān)聽(tīng)系統(tǒng)啟動(dòng)案例

創(chuàng)建 receiver

我們可以右鍵點(diǎn)擊項(xiàng)目,來(lái)使用官方提供的模板創(chuàng)建 broadcastreceiver;

這種方式創(chuàng)建后,會(huì)自動(dòng)在 manifest 文件內(nèi)注冊(cè)該外部 receiver,否則會(huì)需要我們手動(dòng)來(lái)進(jìn)行注冊(cè),十分不方便;

我們據(jù)此創(chuàng)建 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()
    }
}

設(shè)置權(quán)限

為了監(jiān)聽(tīng)系統(tǒng)啟動(dòng)廣播,我們需要靜態(tài)注冊(cè)(該廣播事實(shí)上是一個(gè)隱式廣播,但因?yàn)榘踩[患小,安卓并沒(méi)有禁止其靜態(tài)注冊(cè)?。?/p>

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <!-- 在這里注冊(cè)權(quán)限 -->
    <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">

            <!-- 設(shè)置過(guò)濾器 -->
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
            </intent-filter>
        </receiver>
        ...
    </application>
</manifest>

發(fā)送自定義廣播

如何發(fā)送與接收

新建廣播監(jiān)聽(tīng)器文件:CustomReceiver.kt

編寫監(jiān)聽(tīng)到后反應(yīng)

class CustomReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        Toast.makeText(context, "custom receiver", Toast.LENGTH_SHORT).show()
    }
}

在 manifest 中在對(duì)應(yīng)監(jiān)聽(tīng)器下設(shè)置過(guò)濾器

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

主 activity 中設(shè)置點(diǎn)擊按鈕發(fā)送廣播,此時(shí)自定義監(jiān)聽(tīng)器監(jiān)聽(tīng)到信息,彈出 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

因?yàn)樗须[式廣播都無(wú)法使用靜態(tài)注冊(cè),而我們使用的自定義廣播全部都是隱式廣播;

我們只有使用 setPackage 將自身變成顯示廣播,才能推送到隱式廣播接收器;

有序廣播

監(jiān)聽(tīng)器在 manifest 中注冊(cè)時(shí),在過(guò)濾器后加上出現(xiàn)設(shè)置權(quán)限值;

權(quán)限越高的越早能截獲信息;

<intent-filter android:priority="100">

主 activity 使用 sendOrderedBroadcast 來(lái)發(fā)送有序列的廣播;

第一個(gè)參數(shù)是 intent,第二個(gè)參數(shù)我們一般都填 null

sendOrderedBroadcast(intent,null)

自定義廣播的末尾可以加上 abortBroadcast 可以銷毀該廣播,即廣播終止位置到此為止,后面的優(yōu)先級(jí)較低的都無(wú)監(jiān)聽(tīng)器法接受到了

class CustomReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        ...
        // 攔截并銷毀該廣播
        abortBroadcast()
    }
}

原文鏈接:https://blog.csdn.net/delete_you/article/details/127186791

欄目分類
最近更新