Android app能夠發送廣播也能夠接收系統或者其它app發送的廣播,是發送/訂閱的設計模式。這些廣播被髮送當重要的事件發生的時候。例如,安卓系統發送廣播當各類各樣系統事件發生的時候,好比手機啓動了或者手機開始充電了。應用也能夠發送自定義廣播,例如通知其它應用一些他們可能感興趣的東西,好比一些新的內容被下載了。android
系統廣播會在系統事件發生的時候被髮送出來,好比當手機進入或者退出開發者選項的時候,全部訂閱了系統廣播的人均可以收到這個廣播。設計模式
廣播它自身是被包裹在了一個Intent裏面,它是有一個惟一的標識的(例如android.intent.action.AIRPLANE_MODE)。這個Intent對象同時包含了一些其它的信息,在它的字段裏面,飛行模式這個intent裏面就包含了一個boolean的字段來表示飛行模式是開啓仍是關閉的。網絡
從不一樣的緯度區分,可能分爲不一樣的類別。app
<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>
val br: BroadcastReceiver = MyBroadcastReceiver() val filter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION).apply { addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED) } registerReceiver(br, filter)
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"/>
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"/>
從Android 9(API level 28)開始,NETWORK_STATE_CHANGED_ACTION
廣播不會攜帶用戶的地理位置信息或者我的身份數據。 此外,當你的app運行在Android 9或者更高的手機上,系統的wifi廣播也不會攜帶SSIDs, BSSIDs,鏈接信息或掃描結果。想獲取以上信息,須要經過getConnectionInfo()
來代替。ide
從Android 8(API level 27)開始,系統增強了對靜態廣播的進一步限制,許多廣播靜態註冊了也是收不到的,不過你能夠採用動態註冊的方式來接收這些廣播。學習
從Android 7(API level 24)開始,系統不會再發送ACTION_NEW_PICTURE
,ACTION_NEW_VIDEO
的廣播。 同時從7.0開始app想要接受CONNECTIVITY_ACTION
廣播,須要經過動態註冊廣播的形式了,再經過靜態廣播註冊的方式是不能夠的了。ui
看圖吧,畫了一幅圖設計
衆所周知廣播是會形成ANR的,形成ANR就是由於發送方將廣播發送給AMS,而後AMS找有沒有人註冊,找到以後讓它去執行,在執行開始以前AMS就開始爲ANR進行耗時統計了,若是這個時候app進程已經存在,那麼便把這個消息加入到消息隊列中,等待調度,最後執行完成。若是app不存在,AMS會拉活咱們的進程,而後咱們的app會執行這個消息,因此若是咱們被廣播拉活,咱們的啓動時長也是會被統計到ANR的時間範圍內的。 今年年初我花一個月的時間收錄整理了一套知識體系,若是有想法深刻的系統化的去學習的,能夠點擊傳送門,我會把我收錄整理的資料都送給你們,幫助你們更快的進階。code