Android廣播那些事—開發者必需要知道的面試技巧

一、請描述一下 BroadcastReceiver

BroadCastReceiver 是 Android 四大組件之一,主要用於接收系統或者 app 發送的廣播事件。android

廣播分兩種:
  • 有序廣播
  • 無序廣播。
內部通訊實現機制:
經過 Android 系統的 Binder 機制實現通訊。複製代碼
無序廣播:

徹底異步,邏輯上能夠被任何廣播接收者接收到。優勢是效率較高。缺點是一個接收者不能將處理結果傳遞給下一個接收者,並沒有法終止廣播 intent 的傳播。web

有序廣播:

按照被接收者的優先級順序,在被接收者中依次傳播。好比有三個廣播接收者 A,B,C,優先級是 A > B > C。那這個消息先傳給 A,再傳給 B,最後傳給 C。每一個接收者有權終止廣播,好比 B 終止廣播,C 就沒法接收到。此外 A 接收到廣播後能夠對結果對象進行操做,當廣播傳給 B 時,B 能夠從結果對象中取得 A 存入的數據。設計模式

在經過bash

Context.sendOrderedBroadcast(intent, receiverPermission, resultReceiver, scheduler,initialCode, initialData,initialExtras)複製代碼

時咱們能夠指定 resultReceiver 廣播接收者,這個接收者咱們
能夠認爲是最終接收者,一般狀況下若是比他優先級更高的接收者若是沒有終止廣播,那麼他的onReceive會被執行兩次,第一次是正常的按照優先級順序執行,第二次是做爲最終接收者接收。微信

若是比他優先級高的接收者終止了廣播,那麼他依然能接收到廣播。架構

應用場景

在咱們的項目中常常使用廣播接收者接收系統通知,好比開機啓動、sd 掛載、低電量、外播電話、鎖屏等。app

若是咱們作的是播放器,那麼監聽到用戶鎖屏後咱們應該將咱們的播放之暫停等。異步

二、在 manifest 和代碼中如何註冊和使用 BroadcastReceiver

靜態註冊

在清單文件中註冊廣播接收者稱爲靜態註冊,在代碼中註冊稱爲動態註冊。靜態註冊的廣播接收者只要 app 在系統中運行則一直能夠接收到廣播消息,動態註冊的廣播接收者當註冊的 Activity 或者 Service 銷燬了那麼就接收不到廣播了。ide

在清單文件中進行以下配置測試

<receiver android:name=".BroadcastReceiver1" >
<intent-filter>
<action android:name="android.intent.action.CALL" >
</action>
</intent-filter>
</receiver>複製代碼
動態註冊

動態註冊:在代碼中進行以下注冊

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. 設計模式上(反轉控制的一種應用,相似監聽者模式)

android 中什麼是隱式廣播

Intent intent = new Intent(); intent.setType("image/*"); //經過type來讓系統選擇 視頻video/* intent.setAction(Intent.ACTION_GET_CONTENT);複製代碼

Android7.0的自定義廣播

Android7.0新增的廣播權限驗證問題

好比項目上須要使用廣播進行跨進程通訊,在7.0以前的版本測試都是OK,在7.0上搞死接收不到發送的廣播,關鍵不是這個,關鍵是廣播由於權限問題被拒接,系統不會報錯,也不會拋異常(大概是由於異常被內部捕獲了),最後在輸出的log中進行全局搜索才肯定的問題所在!!!

解決

解決方法其實很簡單,就是在廣播接受者所在的進程聲明一個權限,在廣播的發送者所在的進程內註冊使用該權限,這樣問題就能夠解決了(這種廣播權限問題只存在跨進程靜態註冊廣播的方式上,動態註冊的廣播好像不存在這種問題!!!)

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.permissionbroadcastreceiver">

    <permission
        android:name="com.example.broadcast.permission"
        android:protectionLevel="normal" />
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <receiver android:name=".PermissionRecevicer"
            android:permission="com.example.broadcast.permission">
            <intent-filter>
                <action android:name="com.example.permissionbroadcastreceiver.message" />
            </intent-filter>
        </receiver>
    </application>

</manifest>複製代碼

廣播接收沒有權限以完美解決!!!

更多閱讀

熱修復實戰-史上講解最詳細的文章,強烈推薦

NDK項目實戰—高仿360手機助手之卸載監聽

一個強大的AutoLifecycle—讓普通 Java 類自動感知 Activity Lifecycle

微信公衆號:終端研發部

技術+職場
技術+職場
相關文章
相關標籤/搜索