日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android四大组件——BroadcastReceiver详解

發布時間:2023/12/20 Android 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android四大组件——BroadcastReceiver详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、 定義

  • BroadcastReceiver(廣播接收器),屬于Android四大組件之一
  • 在Android開發中,BroadcastReceiver的應用場景非常多廣播,是一個全局的監聽器,屬于Android四大組件之一

Android 廣播分為兩個角色:廣播發送者、廣播接收者

二、 作用

  • 用于監聽 / 接收 應用發出的廣播消息,并做出響應

  • 應用場景
    a. 不同組件之間通信(包括應用內 / 不同應用之間)

    b. 與 Android 系統在特定情況下的通信

    如當電話呼入時、網絡可用時

    c. 多線程通信

三、實現原理

  • Android中的廣播使用了設計模式中的觀察者模式:基于消息的發布/訂閱事件模型。

    因此,Android將廣播的發送者 和 接收者 解耦,使得系統方便集成,更易擴展

  • 模型中有3個角色:

  • 消息訂閱者(廣播接收者)
  • 消息發布者(廣播發布者)
  • 消息中心(AMS,即Activity Manager Service)

  • 原理描述:

  • 廣播接收者 通過 Binder機制在 AMS 注冊

  • 廣播發送者 通過 Binder 機制向 AMS 發送廣播

  • AMS 根據 廣播發送者 要求,在已注冊列表中,尋找合適的廣播接收者

    尋找依據:IntentFilter / Permission

  • AMS將廣播發送到合適的廣播接收者相應的消息循環隊列中;

  • 廣播接收者通過 消息循環 拿到此廣播,并回調 onReceive()

特別注意:廣播發送者 和 廣播接收者的執行 是 異步的,發出去的廣播不會關心有無接收者接收,也不確定接收者到底是何時才能接收到;

四、具體使用

具體使用流程如下:

接下來我將一步步介紹如何使用

即上圖中的 開發者手動完成部分

4.1 自定義廣播接收者BroadcastReceiver

  • 繼承自BroadcastReceivre基類

  • 必須復寫抽象方法onReceive()方法

  • 廣播接收器接收到相應廣播后,會自動回調onReceive()方法
  • 一般情況下,onReceive方法會涉及與其他組件之間的交互,如發送Notification、啟動service等
  • 默認情況下,廣播接收器運行在UI線程,因此,onReceive方法不能執行耗時操作,否則將導致ANR。
  • 代碼范例
    mBroadcastReceiver.java

public class mBroadcastReceiver extends BroadcastReceiver {//接收到廣播后自動調用該方法@Overridepublic void onReceive(Context context, Intent intent) {//寫入接收廣播后的操作} }

4.2 廣播接收器注冊

注冊的方式分為兩種:靜態注冊、動態注冊

4.2.1 靜態注冊

  • 在AndroidManifest.xml里通過 <receive> 標簽聲明
  • 屬性說明:
<receiverandroid:enabled=["true" | "false"]//此broadcastReceiver能否接收其他App的發出的廣播//默認值是由receiver中有無intent-filter決定的:如果有intent-filter,默認值為true,否則為falseandroid: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//此廣播接收者類是mBroadcastReceiverandroid:name=".mBroadcastReceiver" >//用于接收網絡狀態改變時發出的廣播<intent-filter><action android:name="android.net.conn.CONNECTIVITY_CHANGE" /></intent-filter> </receiver>

    當此App首次啟動時,系統會自動實例化mBroadcastReceiver類,并注冊到系統中。

4.2.2 動態注冊

在代碼中通過調用Context的*registerReceiver()*方法進行動態注冊BroadcastReceiver,具體代碼如下:

@Override protected void onResume() {super.onResume();//實例化BroadcastReceiver子類 & IntentFiltermBroadcastReceiver mBroadcastReceiver = new mBroadcastReceiver();IntentFilter intentFilter = new IntentFilter();//設置接收廣播的類型intentFilter.addAction(android.net.conn.CONNECTIVITY_CHANGE);//調用Context的registerReceiver()方法進行動態注冊registerReceiver(mBroadcastReceiver, intentFilter); }//注冊廣播后,要在相應位置記得銷毀廣播 //即在onPause() 中unregisterReceiver(mBroadcastReceiver) //當此Activity實例化時,會動態將MyBroadcastReceiver注冊到系統中 //當此Activity銷毀時,動態注冊的MyBroadcastReceiver將不再接收到相應的廣播。 @Override protected void onPause() {super.onPause();//銷毀在onResume()方法中的廣播unregisterReceiver(mBroadcastReceiver); }

特別注意

  • 動態廣播最好在Activity的onResume()注冊、onPause()注銷。

  • 原因:

    對于動態廣播,有注冊就必然得有注銷,否則會導致內存泄露

    重復注冊、重復注銷也不允許

4.2.3 兩種注冊方式的區別

4.3 廣播發送者向AMS發送廣播

4.3.1 廣播的發送

  • 廣播是用”意圖(Intent)“標識
  • 定義廣播的本質:定義廣播所具備的“意圖(Intent)”
  • 廣播發送:廣播發送者將此廣播的”意圖“通過sendBroadcast()方法發送出去

4.3.2 廣播的類型

廣播的類型主要分為5類:

  • 普通廣播(Normal Broadcast)
  • 系統廣播(System Broadcast)
  • 有序廣播(Ordered Broadcast)
  • 粘性廣播(Sticky Broadcast)
  • App應用內廣播(Local Broadcast)

具體說明如下:

①. 普通廣播(Normal Broadcast)

即開發者自身定義intent的廣播(最常用)。發送廣播使用如下:

Intent intent = new Intent(); //對應BroadcastReceiver中intentFilter的action intent.setAction(BROADCAST_ACTION); //發送廣播 sendBroadcast(intent);
  • 若被注冊了的廣播接收者中注冊時intentFilter的action與上述匹配,則會接收此廣播(即進行回調onReceive())。如下mBroadcastReceiver則會接收上述廣播
<receiver //此廣播接收者類是mBroadcastReceiverandroid:name=".mBroadcastReceiver" >//用于接收網絡狀態改變時發出的廣播<intent-filter><action android:name="BROADCAST_ACTION" /></intent-filter> </receiver>
  • 若發送廣播有相應權限,那么廣播接收者也需要相應權限

②. 系統廣播(System Broadcast)

  • Android中內置了多個系統廣播:只要涉及到手機的基本操作(如開機、網絡狀態變化、拍照等等),都會發出相應的廣播
  • 每個廣播都有特定的Intent - Filter(包括具體的action),Android系統廣播action如下:
系統操作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
成功安裝APKIntent.ACTION_PACKAGE_ADDED
成功刪除APKIntent.ACTION_PACKAGE_REMOVED
重啟設備Intent.ACTION_REBOOT
屏幕被關閉Intent.ACTION_SCREEN_OFF
屏幕被打開Intent.ACTION_SCREEN_ON
關閉系統時Intent.ACTION_SHUTDOWN
重啟設備Intent.ACTION_REBOOT

注:當使用系統廣播時,只需要在注冊廣播接收者時定義相關的action即可,并不需要手動發送廣播,當系統有相關操作時會自動進行系統廣播

③. 有序廣播(Ordered Broadcast)

  • 定義
    發送出去的廣播被廣播接收者按照先后順序接收

    有序是針對廣播接收者而言的

  • 廣播接受者接收廣播的順序規則(同時面向靜態和動態注冊的廣播接受者)

  • 按照Priority屬性值從大-小排序;
  • Priority屬性相同者,動態注冊的廣播優先;
  • 特點

  • 接收廣播按順序接收
  • 先接收的廣播接收者可以對廣播進行截斷,即后接收的廣播接收者不再接收到此廣播;
  • 先接收的廣播接收者可以對廣播進行修改,那么后接收的廣播接收者將接收到被修改后的廣播
  • 具體使用
    有序廣播的使用過程與普通廣播非常類似,差異僅在于廣播的發送方式:

    sendOrderedBroadcast(intent);

④. App應用內廣播(Local Broadcast)

  • 背景
    Android中的廣播可以跨App直接通信(exported對于有intent-filter情況下默認值為true)

  • 沖突
    可能出現的問題:

    • 其他App針對性發出與當前App intent-filter相匹配的廣播,由此導致當前App不斷接收廣播并處理;
    • 其他App注冊與當前App一致的intent-filter用于接收廣播,獲取廣播具體信息;
      即會出現安全性 & 效率性的問題。
  • 解決方案
    使用App應用內廣播(Local Broadcast)

  • App應用內廣播可理解為一種局部廣播,廣播的發送者和接收者都同屬于一個App。
  • 相比于全局廣播(普通廣播),App應用內廣播優勢體現在:安全性高 & 效率高
  • 具體使用1 - 將全局廣播設置成局部廣播

  • 注冊廣播時將exported屬性設置為false,使得非本App內部發出的此廣播不被接收;

  • 在廣播發送和接收時,增設相應權限permission,用于權限驗證;

  • 發送廣播時指定該廣播接收器所在的包名,此廣播將只會發送到此包中的App內與之相匹配的有效廣播接收器中。

    通過 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);

⑤. 粘性廣播(Sticky Broadcast)

由于在Android5.0 & API 21中已經失效。

總結

以上是生活随笔為你收集整理的Android四大组件——BroadcastReceiver详解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。