Android四大組件之broadcast廣播詳解
基礎廣播
兩大類廣播
標準廣播:異步執(zhí)行,廣播發(fā)出后所有 receiver 同時接收,無先后順序,無法被截斷;
有序廣播:同步執(zhí)行,類似于中間件,每個 receiver 攔截廣播后有權將其下放到下一個 receiver 或者直接截斷;
廣播的動態(tài)和靜態(tài)注冊
動態(tài)注冊:寫在代碼里面的監(jiān)聽事件;
靜態(tài)注冊:寫在 manifest.xml 里面的監(jiān)聽;
目前,由于安卓為了維護用戶系統(tǒng)安全,故所有的隱式廣播均不允許靜態(tài)注冊
監(jiān)聽時間變化
在主 activity 里面編寫如下代碼,實現(xiàn)每隔一分鐘監(jiān)聽一次時間變化并 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)聽器 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") // 實例化監(jiān)聽器 timeChangeReceiver = TimeChangeReceiver() // 注冊廣播監(jiān)聽器 registerReceiver(timeChangeReceiver, intentFilter) } override fun onDestroy() { super.onDestroy() // 銷毀activity的時候別忘了注銷廣播監(jiān)聽器 unregisterReceiver(timeChangeReceiver) } // 使用內部類動態(tài)注冊廣播監(jiān)聽器 inner class TimeChangeReceiver : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { Toast.makeText(context, "time changed", Toast.LENGTH_SHORT).show() } } }
監(jiān)聽系統(tǒng)啟動案例
創(chuàng)建 receiver
我們可以右鍵點擊項目,來使用官方提供的模板創(chuàng)建 broadcastreceiver;
這種方式創(chuàng)建后,會自動在 manifest 文件內注冊該外部 receiver,否則會需要我們手動來進行注冊,十分不方便;
我們據(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() } }
設置權限
為了監(jiān)聽系統(tǒng)啟動廣播,我們需要靜態(tài)注冊(該廣播事實上是一個隱式廣播,但因為安全隱患小,安卓并沒有禁止其靜態(tài)注冊?。?/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"> <!-- 在這里注冊權限 --> <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>
發(fā)送自定義廣播
如何發(fā)送與接收
新建廣播監(jiān)聽器文件:CustomReceiver.kt
編寫監(jiān)聽到后反應
class CustomReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { Toast.makeText(context, "custom receiver", Toast.LENGTH_SHORT).show() } }
在 manifest 中在對應監(jiān)聽器下設置過濾器
<receiver android:name=".BootReceiver" android:enabled="true" android:exported="true"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> </intent-filter> </receiver>
主 activity 中設置點擊按鈕發(fā)送廣播,此時自定義監(jiān)聽器監(jiān)聽到信息,彈出 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
因為所有隱式廣播都無法使用靜態(tài)注冊,而我們使用的自定義廣播全部都是隱式廣播;
我們只有使用 setPackage 將自身變成顯示廣播,才能推送到隱式廣播接收器;
有序廣播
監(jiān)聽器在 manifest 中注冊時,在過濾器后加上出現(xiàn)設置權限值;
權限越高的越早能截獲信息;
<intent-filter android:priority="100">
主 activity 使用 sendOrderedBroadcast 來發(fā)送有序列的廣播;
第一個參數(shù)是 intent,第二個參數(shù)我們一般都填 null
sendOrderedBroadcast(intent,null)
自定義廣播的末尾可以加上 abortBroadcast 可以銷毀該廣播,即廣播終止位置到此為止,后面的優(yōu)先級較低的都無監(jiān)聽器法接受到了
class CustomReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { ... // 攔截并銷毀該廣播 abortBroadcast() } }
到此這篇關于Android四大組件之broadcast廣播詳解的文章就介紹到這了,更多相關Android broadcast內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Android UI控件ExpandableListView基本用法詳解
這篇文章主要為大家詳細介紹了Android UI控件ExpandableListView基本用法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-09-09