Android?

Android 面試題總結之Android 基礎 希望能幫助到大家

方法/步驟

Broadcast Receiver 常見面試題

BroadcastReceiver 簡介

BroadCastReceiver 是 Android 四大元件之一,主要用於接收系統或者 app 發 送的廣播事件。 廣播分兩種:有序廣播和無序廣播。 內部通訊實現機制:通過 Android 系統的 Binder 機制實現通訊。 無序廣播:完全非同步,邏輯上可以被任何廣播接收者接收到。優點是效率較高。 缺點是一個接收者不能將處理結果傳遞給下一個接收者,並無法終止廣播 intent 的傳播。 有序廣播:按照被接收者的優先順序順序,在被接收者中依次傳播。比如有三個廣 播接收者 A,B,C,優先順序是 A > B > C。那這個訊息先傳給 A,再傳給 B,最 後傳給 C。每個接收者有權終止廣播,比如 B 終止廣播,C 就無法接收到。此外 A 接收到廣播後可以對結果物件進行操作,當廣播傳給 B 時,B 可以從結果物件 中取得 A 存入的資料。

在通過 Context.sendOrderedBroadcast(intent, receiverPermission, resultReceiver, scheduler, initialCode, initialData, initialExtras)時我們可以 指定 resultReceiver 廣播接收者,這個接收者我們可以認為是最終接收者,通 常情況下如果比他優先順序更高的接收者如果沒有終止廣播,那麼他的 onReceive 會被執行兩次,第一次是正常的按照優先順序順序執行,第二次是作為最終接收者 接收。如果比他優先順序高的接收者終止了廣播,那麼他依然能接收到廣播。 在我們的專案中經常使用廣播接收者接收系統通知,比如開機啟動、sd 掛載、 低電量、外播電話、鎖屏等。 如果我們做的是播放器,那麼監聽到使用者鎖屏後我們應該將我們的播放之暫停 等。

Android 4.0之後,如果系統自動關閉廣播接收者所在程序,在廣播中的action跟廣播接收者的action匹配時,系統會啟動該廣播所在的程序,但是如果是使用者手動關閉該程序,則不會自啟動,只有等使用者手動開啟,廣播接收者所在程序如果從來沒有啟動過,那麼廣播接收者不會生效

在 manifest 和程式碼中如何註冊和使用 BroadcastReceiver 在清單檔案中註冊廣播接收者稱為靜態註冊,在程式碼中註冊稱為動態註冊。 靜態註冊的廣播接收者只要 app 在系統中執行則一直可以接收到廣播訊息,動 態註冊的廣播接收者當註冊的 Activity 或者 Service 銷燬了那麼就接收不到廣播 了。

靜態註冊:在清單檔案中進行如下配置

動態註冊:在程式碼中進行如下注冊

receiver = new BroadcastReceiver(); IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(CALL_ACTION); context.registerReceiver(receiver, intentFilter);

BroadCastReceiver 的生命週期 a. 廣播接收者的生命週期非常短暫的,在接收到廣播的時候建立, onReceive()方法結束之後銷燬; b. 廣播接收者中不要做一些耗時的工作,否則會彈出 Application No Response 錯誤對話方塊; c. 最好也不要在廣播接收者中建立子執行緒做耗時的工作,因為廣播接收者被 銷燬後進程就成為了空程序,很容易被系統殺掉; d. 耗時的較長的工作最好放在服務中完成;

Android 引入廣播機制的用意

a. 從 MVC 的角度考慮(應用程式內) 其實回答這個問題的時候還可以這樣問, android 為什麼要有那 4 大元件,現在的移動開發模型基本上也是照搬的 web 那一套 MVC 架構,只不過是改了點嫁妝而已。android 的四大元件本 質上就是為了實現移動或者說嵌入式裝置上的 MVC 架構,它們之間有時候 是一種相互依存的關係,有時候又是一種補充關係,引入廣播機制可以方便 幾大元件的資訊和資料互動。 b. 程式間互通訊息(例如在自己的應用程式內監聽系統來電) c. 效率上(參考 UDP 的廣播協議在區域網的方便性) d. 設計模式上(反轉控制的一種應用,類似監聽者模式)

如何讓自己的廣播只讓指定的 app 接收? 通過自定義廣播許可權來保護自己發出的廣播。 在清單檔案裡receiver必須有這個許可權才能收到廣播。 首先,需要定義許可權: 然後,宣告許可權: 這時接收者就能收到傳送的廣播。

廣播的優先順序對無序廣播生效嗎? 生效的

動態註冊的廣播優先順序誰高? 誰先註冊誰優先順序高。

如何判斷當前 BroadcastReceiver 接收到的是有序廣播還是無序廣播? 在 BroadcastReceiver 類中 onReceive()方法中,可以呼叫 boolean b = isOrderedBroadcast();判斷接收到的廣播是否為有序廣播。

粘性廣播有什麼作用?怎麼使用? 粘性廣播主要為了解決,在傳送完廣播之後,動態註冊的接收者,也能夠收到廣播。舉個例子首先發送一廣播,我的接收者是通過程式中的某個按鈕動態註冊的。如果不是粘性廣播,我註冊完接收者肯定無法收到廣播了。這是通過傳送粘性廣播就能夠在我動態註冊接收者後也能收到廣播。

//傳送粘性廣播

Public void sendStickyBroadCast(){

Intent intent=new Intent();

intent.setAction(“com.iteye.myreceiver.action”);

intent.putExtra(“name”,”tom”);

this.sendStickyBroadCast(intent);

}

傳送粘性廣播還需要傳送粘性廣播的許可權:

什麼是最終廣播接收者? 即使前邊攔截了廣播,還是會收到廣播 最終廣播是我們自己應用傳送有序廣播時通過 ContextWrapper.sendOrderedBroadcast()方法指定的當前應用 下的廣播,該廣播可能會被執行兩次,第一次是作為普通廣播按照優先順序接收廣播,第二次是作為 final receiver 必須 接收一次。

LocalBroadcastManager (區域性通知管理器)

在android-support-v4.jar中引入了LocalBroadcastManager

LocalBroadcastManager除了能解決BroadcastReceiver程序間安全性問題外,相對Context操作的BroadcastReceiver而言還具有更高的執行效率。 本地廣播通過LocalBroadcastManager.getInstance(context).sendBroadcast(intent)傳送廣播, LocalBroadcastManager.getInstance(context).registerReceiver註冊服務,通過LocalBroadcastManager.getInstance(context).unregisterReceiver取消註冊服務,其他同普通廣播。 BroadcastReceiver的通訊是走 Binder 機制的,LocalBroadcastManager 的核心實現實際還是 Handler,只是利用到了 IntentFilter 的 match 功能,因為是 Handler 實現的應用內的通訊,自然安全性更好,效率更高。

通常使用BroadcastReceiver進行工作執行緒的任務結果通知也好,還是程序間安全性問題,容易引起效能問題,那麼使用LocalBroadcastManager.getInstance有效提高了安全性和效能。

關於BroadcastReceiver相關面試問題,本章節就先總結到這來。希望對大家有所幫助。

相關問題答案