Android中BroadcastReceiver詳解

BroadcastReceiver是什麼?

Android app能夠發送廣播也能夠接收系統或者其它app發送的廣播,是發送/訂閱的設計模式。這些廣播被髮送當重要的事件發生的時候。例如,安卓系統發送廣播當各類各樣系統事件發生的時候,好比手機啓動了或者手機開始充電了。應用也能夠發送自定義廣播,例如通知其它應用一些他們可能感興趣的東西,好比一些新的內容被下載了。android

系統廣播會在系統事件發生的時候被髮送出來,好比當手機進入或者退出開發者選項的時候,全部訂閱了系統廣播的人均可以收到這個廣播。設計模式

廣播它自身是被包裹在了一個Intent裏面,它是有一個惟一的標識的(例如android.intent.action.AIRPLANE_MODE)。這個Intent對象同時包含了一些其它的信息,在它的字段裏面,飛行模式這個intent裏面就包含了一個boolean的字段來表示飛行模式是開啓仍是關閉的。網絡

BroadcastReceiver能用來作什麼?

  1. 接收系統發送出的重要的廣播(網絡變化,開機,充電)
  2. app之間相互通訊,相互拉活的手段
  3. app內部組建間通訊的手段

BroadcastReceiver分爲哪幾類?

從不一樣的緯度區分,可能分爲不一樣的類別。app

  1. 系統廣播/非系統廣播
  2. 全局廣播/本地廣播
  3. 無序廣播/有序廣播/粘性廣播

BroadcastReceiver怎麼使用?

1. 註冊廣播

1.1 靜態註冊廣播

<receiver android:name=".MyBroadcastReceiver"  android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
        <action android:name="android.intent.action.INPUT_METHOD_CHANGED" />
    </intent-filter>
</receiver>

1.2 動態註冊廣播

val br: BroadcastReceiver = MyBroadcastReceiver()
val filter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION).apply {
    addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED)
}
registerReceiver(br, filter)

2. 發送廣播

Intent().also { intent ->
    intent.setAction("com.example.broadcast.MY_NOTIFICATION")
    intent.putExtra("data", "Notice me senpai!")
    sendBroadcast(intent)
}
sendBroadcast(Intent("com.example.NOTIFY"), Manifest.permission.SEND_SMS)
<uses-permission android:name="android.permission.SEND_SMS"/>

3. 接收廣播

private const val TAG = "MyBroadcastReceiver"

class MyBroadcastReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {
        StringBuilder().apply {
            append("Action: ${intent.action}\n")
            append("URI: ${intent.toUri(Intent.URI_INTENT_SCHEME)}\n")
            toString().also { log ->
                Log.d(TAG, log)
                Toast.makeText(context, log, Toast.LENGTH_LONG).show()
            }
        }
    }
}
<receiver android:name=".MyBroadcastReceiver"
          android:permission="android.permission.SEND_SMS">
    <intent-filter>
        <action android:name="android.intent.action.AIRPLANE_MODE"/>
    </intent-filter>
</receiver>
var filter = IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED)
registerReceiver(receiver, filter, Manifest.permission.SEND_SMS, null )
<uses-permission android:name="android.permission.SEND_SMS"/>

BroadcastReceiver在不一樣版本的API中有哪些區別?

Android 9

從Android 9(API level 28)開始,NETWORK_STATE_CHANGED_ACTION廣播不會攜帶用戶的地理位置信息或者我的身份數據。 此外,當你的app運行在Android 9或者更高的手機上,系統的wifi廣播也不會攜帶SSIDs, BSSIDs,鏈接信息或掃描結果。想獲取以上信息,須要經過getConnectionInfo()來代替。ide

Android 8

從Android 8(API level 27)開始,系統增強了對靜態廣播的進一步限制,許多廣播靜態註冊了也是收不到的,不過你能夠採用動態註冊的方式來接收這些廣播。學習

Android 7

從Android 7(API level 24)開始,系統不會再發送ACTION_NEW_PICTURE,ACTION_NEW_VIDEO的廣播。 同時從7.0開始app想要接受CONNECTIVITY_ACTION廣播,須要經過動態註冊廣播的形式了,再經過靜態廣播註冊的方式是不能夠的了。ui

BroadcastReceiver發送廣播和接收廣播是怎樣工做的?

看圖吧,畫了一幅圖設計

BroadcastReceiver是怎麼引起ANR的?

衆所周知廣播是會形成ANR的,形成ANR就是由於發送方將廣播發送給AMS,而後AMS找有沒有人註冊,找到以後讓它去執行,在執行開始以前AMS就開始爲ANR進行耗時統計了,若是這個時候app進程已經存在,那麼便把這個消息加入到消息隊列中,等待調度,最後執行完成。若是app不存在,AMS會拉活咱們的進程,而後咱們的app會執行這個消息,因此若是咱們被廣播拉活,咱們的啓動時長也是會被統計到ANR的時間範圍內的。 今年年初我花一個月的時間收錄整理了一套知識體系,若是有想法深刻的系統化的去學習的,能夠點擊傳送門,我會把我收錄整理的資料都送給你們,幫助你們更快的進階。code

相關文章
相關標籤/搜索