Android apps can send or receive broadcast messages from the Android system and other Android apps, similar to the publish-subscribe design pattern. These broadcasts are sent when an event of interest occurs. For example, the Android system sends broadcasts when various system events occur, such as when the system boots up or the device starts charging. Apps can also send custom broadcasts, for example, to notify other apps of something that they might be interested in (for example, some new data has been downloaded).
上述是Android對于BroadCast的官方解釋,從這里可以看出Broadcast是一種廣泛運用的在應用之間傳輸信息的機制,Android中我們要發送的廣播內容是一個Intent,這個Intent攜帶了我們要傳輸的數據。
在Android系統中,為什么需要廣播機制呢?廣播機制,本質上它就是一種組件間的通信方式,如果是兩個組件位于不同的進程當中,那么可以用Binder機制來實現,如果兩個組件是在同一個進程中,那么它們之間可以用來通信的方式就更多了,這樣看來,廣播機制似乎是多余的。然而,廣播機制卻是不可替代的,它和Binder機制不一樣的地方在于,廣播的發送者和接收者事先是不需要知道對方的存在的,這樣帶來的好處便是,系統的各個組件可以松耦合地組織在一起,這樣系統就具有高度的可擴展性,容易與其它系統進行集成。
在軟件工程中,是非常強調模塊之間的高內聚低耦合性的,不然的話,隨著系統越來越龐大,就會面臨著越來越難維護的風險,最后導致整個項目的失敗。Android應用程序的組織方式,可以說是把這種高內聚低耦合性的思想貫徹得非常透徹,在任何一個Activity中,都可以使用一個簡單的Intent,通過startActivity或者startService,就可以把另外一個Activity或者Service啟動起來為它服務,而且它根本上不依賴這個Activity或者Service的實現,只需要知道它的字符串形式的名字即可,而廣播機制更絕,它連接收者的名字都不需要知道。
1. 廣播使用場景
- 同一APP具有多個進程的不同組件之間的消息通信
- 不同app之間的組件之間的消息通信
2. 廣播種類
1. Normal BroadCast:Context.sendBroadCast
無序廣播:該廣播調用sendBroadCast()方法來發送廣播的。無序廣播不可以被攔截,若被攔截,則會報錯。所有接受無序廣播的廣播接收者在此廣播被發送時均能接收到該無序廣播。無序廣播的廣播接收者之間不能相互傳遞數據。
2. System BroadCast:Context.sendOrderedBroadCast
有序廣播:該廣播是調用sendOrderedBroadCast()方法來發送廣播的,同時也可以調用abortBroadcast()方法來攔截該廣播。有序廣播的廣播接收者可以在清單文件中,通過
<intent-filter>
標簽設置"android:property"
屬性來設置優先級,優先級高的接收者可以攔截優先級低的。
在相同優先級下,廣播接收者接受的順序要看接收者在清單文件中聲明的順序,先聲明的接收者比后聲明的接收者要先接收到廣播。有序廣播的廣播接收者之間可以互相傳遞數據。
3. Local BroadCast:只在自身app內傳播
3. 廣播接收者的注冊方式
1. 靜態注冊
直接在AndroidManifest.xml
文件中進行注冊,通過該方式注冊的廣播接收者在系統中運行一次后就會被注冊到系統中,以后無須運行該應用程序也可以就收到廣播。
2. 動態注冊
無須在AndroidManifest.xml
文件中注冊<receiver>
組件,直接在代碼中通過調用Context的registerReceiver()
方法即可在程序中動態注冊廣播接收者。通過這種注冊方式注冊的廣播接收者,只有在代碼運行時,廣播接收者才生效。若代碼運行結束,則廣播接收者也即失效。
4. 內部實現機制
- 自定義廣播接收者BroadcastReceiver,并復寫
onReceive()
方法;- 通過Binder機制向AMS進行注冊;
- 廣播發送者通過Binder機制向AMS發送廣播;
- AMS查找符合相應條件(IntentFilter/Permission等)的BroadcastReceiver,將廣播發送到BroadcastReceiver(一般情況下是Activity)相應的消息循環隊列中;
- 消息循環執行拿到此廣播,回調BroadcastReceiver中的onReceive()方法。
5. LocalBroadCastManager
- 使用它發送的廣播將只在自身App內傳播,因此不必擔心泄露隱私數據;
- 其他App無法對你的App發送該廣播,因為你的App根本就接收不到非自身應用發送的該廣播,因此不必擔心安全漏洞問題;
- 比系統的全局廣播更加高效
- localBroadcastManager高效的原因主要是因為它內部是通過Handler實現的,它的sendBroadcast()其實是通過handler發送一個Message實現的;
- 相比與系統方便通過Binder實現肯定是高效,同時使用Handler來實現,別的應用無法向我們的應用發送該廣播,而我們應用內發送的廣播也不會離開我們的應用;
- localBroadcastManager內部協作主要是靠mReceivers和mActions這兩個Map集合,當然還有一個List集合mPendingBroadcasts,這個主要是存儲待接收的廣播對象。
6. 其他
關于BroadcastReceiver使用需要注意的幾點:
- onReceive中不能執行耗時操作,如果耗時超過10s會彈出ANR。
- onReceive中context參數,如果是靜態注冊的廣播,context為ReceiverRestrictedContext,所在如果在這里要啟動一個Activity的話(調用startActivity),需要在intent中添加Intent.FLAG_ACTIVITY_NEW_TASK;如果是動態注冊的廣播,context為當前注冊時所在的組件,比如Activity或者Service。
- 監聽系統廣播,需要在AndroidManifest中申請權限,此外,Android高版本系統對于一些重要的系統廣播,比如開機啟動,網絡連接,電量變化,鎖屏等做了限制,如果需要監聽這些廣播,需要做系統兼容性處理。
- 普通廣播的廣播接收器是并行無序執行的,有序廣播的廣播接收器按照廣播優先級串行執行