嗨,你終於來啦 ~ 等你很久啦~ 喜歡的小夥伴歡迎關注,我會按期分享Android知識點及解析,還會不斷更新的BATJ面試專題,歡迎你們前來探討交流,若有好的文章也歡迎投稿。javascript
以前有些小夥伴私信我,想讓我說說關於Android四大組件的問題,這段時間工做上比較忙,因此就擱置了下來~今天項目終於告一段落,因此我決定從這篇起分別說一下關於四大組件的深刻知識~java
你們都知道BroadcastReceiver
(廣播接收器),屬於 Android
四大組件之一在 Android
開發中,BroadcastReceiver
的應用場景很是多,因此今天第一篇,我將詳細講解關於BroadcastReceiver
的一切相關知識。android
即 廣播,是一個全局的監聽器,屬於Android
四大組件之一面試
Android
廣播分爲兩個角色:廣播發送者、廣播接收者設計模式
監聽 / 接收 應用 App
發出的廣播消息,並 作出響應安全
Android
不一樣組件間的通訊(含 :應用內 / 不一樣應用之間)Android
系統在特定狀況下的通訊如:電話呼入時、網絡可用時網絡
Android
中的廣播使用了設計模式中的觀察者模式:基於消息的發佈 / 訂閱事件模型所以,Android將廣播的發送者 和 接收者 解耦,使得系統方便集成,更易擴展多線程
模型中有3個角色:app
AMS
,即Activity Manager Service
)示意圖 & 原理以下ide
BroadcastReceiver
即上圖中的 開發者手動完成部分
BroadcastReceivre
基類onReceive()
方法
- 廣播接收器接收到相應廣播後,會自動回調
onReceive()
方法- 通常狀況下,
onReceive
方法會涉及 與 其餘組件之間的交互,如發送Notification
、啓動Service
等- 默認狀況下,廣播接收器運行在
UI
線程,所以,onReceive()
方法不能執行耗時操做,不然將致使ANR
// 繼承BroadcastReceivre基類
public class mBroadcastReceiver extends BroadcastReceiver {
// 複寫onReceive()方法
// 接收到廣播後,則自動調用該方法
@Override
public void onReceive(Context context, Intent intent) {
//寫入接收廣播後的操做
}
}
複製代碼
註冊的方式分爲兩種:靜態註冊、動態註冊
<receiver
android:enabled=["true" | "false"]
//此broadcastReceiver可否接收其餘App的發出的廣播
//默認值是由receiver中有無intent-filter決定的:若是有intent-filter,默認值爲true,不然爲false
android:exported=["true" | "false"]
android:icon="drawable resource"
android:label="string resource"
//繼承BroadcastReceiver子類的類名
android:name=".mBroadcastReceiver"
//具備相應權限的廣播發送者發送的廣播才能被此BroadcastReceiver所接收;
android:permission="string"
//BroadcastReceiver運行所處的進程
//默認爲app的進程,能夠指定獨立的進程
//注:Android四大基本組件均可以經過此屬性指定本身的獨立進程
android:process="string" >
//用於指定此廣播接收器將接收的廣播類型
//本示例中給出的是用於接收網絡狀態改變時發出的廣播
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> </intent-filter> </receiver>
複製代碼
<receiver
//此廣播接收者類是mBroadcastReceiver
android:name=".mBroadcastReceiver" >
//用於接收網絡狀態改變時發出的廣播
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> </intent-filter> </receiver>
複製代碼
當此 App
首次啓動時,系統會自動實例化mBroadcastReceiver
類,並註冊到系統中。
註冊方式:在代碼中調用Context.registerReceiver()
方法
具體代碼以下:
// 選擇在Activity生命週期方法中的onResume()中註冊
@Override
protected void onResume(){
super.onResume();
// 1. 實例化BroadcastReceiver子類 & IntentFilter
mBroadcastReceiver mBroadcastReceiver = new mBroadcastReceiver();
IntentFilter intentFilter = new IntentFilter();
// 2. 設置接收廣播的類型
intentFilter.addAction(android.net.conn.CONNECTIVITY_CHANGE);
// 3. 動態註冊:調用Context的registerReceiver()方法
registerReceiver(mBroadcastReceiver, intentFilter);
}
// 註冊廣播後,要在相應位置記得銷燬廣播
// 即在onPause() 中unregisterReceiver(mBroadcastReceiver)
// 當此Activity實例化時,會動態將MyBroadcastReceiver註冊到系統中
// 當此Activity銷燬時,動態註冊的MyBroadcastReceiver將再也不接收到相應的廣播。
@Override
protected void onPause() {
super.onPause();
//銷燬在onResume()方法中的廣播
unregisterReceiver(mBroadcastReceiver);
}
}
複製代碼
Activity
的 onResume()
註冊、onPause()
註銷。重複註冊、重複註銷也不容許
Activity
生命週期以下:Activity生命週期的方法是成對出現的:
在onResume()註冊、onPause()註銷是由於onPause()在App死亡前必定會被執行,從而保證廣播在App死亡前必定會被註銷,從而防止內存泄露。
- 不在onCreate() & onDestory() 或 onStart() & onStop()註冊、註銷是由於:
當系統由於內存不足(優先級更高的應用須要內存,請看上圖紅框)要回收Activity佔用的資源時,Activity在執行完onPause()方法後就會被銷燬,有些生命週期方法onStop(),onDestory()就不會執行。當再回到此Activity時,是從onCreate方法開始執行。- 假設咱們將廣播的註銷放在onStop(),onDestory()方法裏的話,有可能在Activity被銷燬後還未執行onStop(),onDestory()方法,即廣播仍還未註銷,從而致使內存泄露。
- 可是,onPause()必定會被執行,從而保證了廣播在App死亡前必定會被註銷,從而防止內存泄露。
Intent
)「標識Intent
)」Intent
)」經過sendBroadcast()方法發送出去廣播的類型主要分爲5類:
Normal Broadcast
)System Broadcast
)Ordered Broadcast
)Sticky Broadcast
)Local Broadcast
)具體說明以下:
1. 普通廣播(Normal Broadcast)
即 開發者自身定義 intent
的廣播(最經常使用)。發送廣播使用以下:
Intent intent = new Intent();
//對應BroadcastReceiver中intentFilter的action
intent.setAction(BROADCAST_ACTION);
//發送廣播
sendBroadcast(intent);
複製代碼
intentFilter
的action
與上述匹配,則會接收此廣播(即進行回調onReceive()
)。以下mBroadcastReceiver
則會接收上述廣播<receiver
//此廣播接收者類是mBroadcastReceiver
android:name=".mBroadcastReceiver" >
//用於接收網絡狀態改變時發出的廣播
<intent-filter>
<action android:name="BROADCAST_ACTION" /> </intent-filter> </receiver>
複製代碼
2. 系統廣播(System Broadcast)
系統操做 | action |
---|---|
監聽網絡變化 | android.net.conn.CONNECTIVITY_CHANGE |
關閉或打開飛行模式 | Intent.ACTION_AIRPLANE_MODE_CHANGED |
充電時或電量發生變化 | Intent.ACTION_BATTERY_CHANGED |
電池電量低 | Intent.ACTION_BATTERY_LOW |
電池電量充足(即從電量低變化到飽滿時會發出廣播 | Intent.ACTION_BATTERY_OKAY |
系統啓動完成後(僅廣播一次) | Intent.ACTION_BOOT_COMPLETED |
按下照相時的拍照按鍵(硬件按鍵)時 | Intent.ACTION_CAMERA_BUTTON |
屏幕鎖屏 | Intent.ACTION_CLOSE_SYSTEM_DIALOGS |
設備當前設置被改變時(界面語言、設備方向等) | Intent.ACTION_CONFIGURATION_CHANGED |
插入耳機時 | Intent.ACTION_HEADSET_PLUG |
未正確移除SD卡但已取出來時(正確移除方法:設置--SD卡和設備內存--卸載SD卡) | Intent.ACTION_MEDIA_BAD_REMOVAL |
插入外部儲存裝置(如SD卡) | Intent.ACTION_MEDIA_CHECKING |
成功安裝APK | Intent.ACTION_PACKAGE_ADDED |
成功刪除APK | Intent.ACTION_PACKAGE_REMOVED |
重啓設備 | Intent.ACTION_REBOOT |
屏幕被關閉 | Intent.ACTION_SCREEN_OFF |
屏幕被打開 | Intent.ACTION_SCREEN_ON |
關閉系統時 | Intent.ACTION_SHUTDOWN |
重啓設備 | Intent.ACTION_REBOOT |
注:當使用系統廣播時,只須要在註冊廣播接收者時定義相關的action便可,並不須要手動發送廣播,當系統有相關操做時會自動進行系統廣播
3. 有序廣播(Ordered Broadcast)
有序是針對廣播接收者而言的
廣播接受者接收廣播的順序規則(同時面向靜態和動態註冊的廣播接受者)
特色
具體使用
有序廣播的使用過程與普通廣播很是相似,差別僅在於廣播的發送方式:
sendOrderedBroadcast(intent);
複製代碼
4. App應用內廣播(Local Broadcast)
背景
Android中的廣播能夠跨App直接通訊(exported對於有intent-filter狀況下默認值爲true)
衝突
可能出現的問題:
解決方案
使用App應用內廣播(Local Broadcast)
- App應用內廣播可理解爲一種局部廣播,廣播的發送者和接收者都同屬於一個App。
- 相比於全局廣播(普通廣播),App應用內廣播優點體如今:安全性高 & 效率高
具體使用1 - 將全局廣播設置成局部廣播
經過intent.setPackage(packageName)指定報名
具體使用2 - 使用封裝好的LocalBroadcastManager類
使用方式上與全局廣播幾乎相同,只是註冊/取消註冊廣播接收器和發送廣播時將參數的context變成了LocalBroadcastManager的單一實例
注:對於LocalBroadcastManager方式發送的應用內廣播,只能經過LocalBroadcastManager動態註冊,不能靜態註冊
//註冊應用內廣播接收器
//步驟1:實例化BroadcastReceiver子類 & IntentFilter mBroadcastReceiver
mBroadcastReceiver = new mBroadcastReceiver();
IntentFilter intentFilter = new IntentFilter();
//步驟2:實例化LocalBroadcastManager的實例
localBroadcastManager = LocalBroadcastManager.getInstance(this);
//步驟3:設置接收廣播的類型
intentFilter.addAction(android.net.conn.CONNECTIVITY_CHANGE);
//步驟4:調用LocalBroadcastManager單一實例的registerReceiver()方法進行動態註冊
localBroadcastManager.registerReceiver(mBroadcastReceiver, intentFilter);
//取消註冊應用內廣播接收器
localBroadcastManager.unregisterReceiver(mBroadcastReceiver);
//發送應用內廣播
Intent intent = new Intent();
intent.setAction(BROADCAST_ACTION);
localBroadcastManager.sendBroadcast(intent);
複製代碼
5. 粘性廣播(Sticky Broadcast)
因爲在Android5.0 & API 21中已經失效,因此不建議使用,在這裏也不做過多的總結。
對於不一樣註冊方式的廣播接收器回調OnReceive(Context context,Intent intent)中的context返回值是不同的:
Android
中四大組件的BroadcastReceiver
的全部知識,以爲文章不錯的喜歡的小夥伴能夠關注加分享,也歡迎你們前來探討交流。