Android BrocastReceiver解析
簡介
BroadcastReceiver(廣播接收器)是Android四大組件之一,是一個用來響應系統范圍內的廣播組件,可以從Android系統和其它app發送或接收廣播消息,類似于發布 - 訂閱設計模式。其特點是異步的,廣播發送者不會關心有無接收者接收。可應用于不同組件之間的通信、多線程通信和系統在特定情況下的通信。
原理
對于不同的廣播類型,以及不同的BroadcastReceiver注冊方式,具體實現上會有不同。但總體流程大致如下:
消息循環執行拿到此廣播,回調BroadcastReceiver中的onReceive()方法。
類型
- 普通廣播(Normal Broadcast)
普通廣播是完全異步的,通過Context的sendBroadcast()方法來發送,消息傳遞效率比較高,但所有receivers(接收器)的執行順序不確定。缺點是接收器不能將處理結果傳遞給下一個接收器,并且無法在中途終止廣播。
val intent = Intent() intent.action = RECEIVE_TOKEN sendBroadcast(intent)- 系統廣播(System Broadcast)
Android系統中內置了多個系統廣播,只要涉及到手機的基本操作,基本上都會發出相應的系統廣播。如:開機啟動,充電與電量變化,網絡狀態改變,拍照,屏幕關閉與開啟等。每個系統廣播都具有特定的intent-filter,其中主要包括具體的action,系統廣播發出后,將被相應的BroadcastReceiver接收。
- 有序廣播(Ordered Broadcast)
“有序”是針對廣播接收者而言的,指的是發送出去的廣播被BroadcastReceiver按照先后循序接收,通過receiver的intent-filter中的android:priority屬性來設置優先級,優先級從-1000~1000,數越大,優先級越高;priority屬性相同者,動態注冊的廣播優先。其使用過程與普通廣播非常類似,差異僅在于廣播的發送方式通過Context.sendOrderedBroadcast()方法發送。
- App應用內廣播(Local Broadcast)
Android中的廣播可以跨App直接通信,可能會帶來消耗性能和容易引起安全性的問題,為了解決這些問題,將全局廣播設置成局部廣播或者使用封裝好的LocalBroadcastManager(只能動態注冊)類。
設置局部廣播方式:
- 注冊廣播時將exported屬性設置為false
- 增設相應權限permission,用于權限驗證
- 指定該廣播接收器所在的包名
LocalBroadcastManager使用
//注冊廣播,在Activity.onResume注冊 val intentFilter = IntentFilter() val broadcastReceiver = BroadcastReceiver() intentFilter.addAction(RECEIVE_TOKEN) LocalBroadcastManager.getInstance(this).registerReceiver(broadcastReceiver, intentFilter) //發送廣播 val intent = Intent() intent.action = RECEIVE_TOKEN LocalBroadcastManager.getInstance(this).sendBroadcast(intent) //取消廣播,在Activity.onPause取消 LocalBroadcastManager.getInstance(this).unregisterReceiver(broadcastReceiver)注冊
- 靜態注冊
直接在Manifest.xml文件的節點中配置,使用< receiver >標簽聲明,并在標簽內用?< intent-filter >?標簽設置過濾器,該注冊方式不管app是否處于活動狀態,都會進行監聽。
<receiver android:name=".BroadcastReceiver" // 繼承BroadcastReceiver子類的類名android:enabled="boolean" // 能否接收其他App的發出的廣播android:exported="boolean" // 默認值是由receiver中有無intent-filter決定的:如果有intent-filter,默認值為true,否則為falseandroid:icon="drawable resource" // 廣播iconandroid:label="string resource" // 廣播標簽android:permission="string" // 具有相應權限的廣播發送者發送的廣播才能被此BroadcastReceiver所接收android:process="string"> // 指定自己的獨立進程<intent-filter><action android:name="com.fomin.demo.ACTION_RECEIVE_TOKEN"/></intent-filter> </receiver>但需要注意的是,Android8.0系統對靜態廣播做了變更,具體可查看[https://blog.csdn.net/fomin_zhu/article/details/84454042]
- 動態注冊
直接在代碼在代碼中調用Context.registerReceiver()方法注冊和調用unregisterReceiver
取消注冊
動態廣播最好在Activity?的?onResume()注冊、onPause()注銷,是因為對于動態廣播,有注冊就必然得有注銷,否則會導致內存泄露;在onResume()注冊、onPause()注銷是因為onPause()在App死亡前一定會被執行,從而保證廣播在App死亡前一定會被注銷,從而防止內存泄露。
- 兩者區別
- 靜態注冊在Manifest.xml注冊,動態在代碼上調用
- 靜態是常駐的,不受生命周期影響,并且耗電和占內存;而動態是使用才注冊,跟隨組件生命周期
注意
不同注冊方式的廣播接收器回調OnReceive()中的context返回值是不一樣的
- 靜態注冊廣播,content是android.app.ReceiverRestrictedContext,此context非Activity類型,不可直接用來構造AlertDialog
- 動態注冊廣播,傳入onReceive()方法里的Context對象context其實就是調用sendBroadcast()的Activty對象;但LocalBroadcastManager方式返回的是Application Context
轉載于:https://www.cnblogs.com/fomin/p/10490848.html
總結
以上是生活随笔為你收集整理的Android BrocastReceiver解析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: VS2017源代码版本管理
- 下一篇: bzoj4033:[HAOI2015]树