越不懂的越愛裝
大家都同等:IT世界沒有難不難,只有是否了解過
挑戰(zhàn)目錄
什么是安卓中的廣播
是安卓程序之間或單個程序內(nèi)部傳遞消息的機(jī)制之一赃份。
按發(fā)送者(廣播來源)分為系統(tǒng)廣播和自定義廣播涨冀。
按注冊方式分為靜態(tài)注冊廣播和動態(tài)注冊廣播辜膝。
按功能分為系統(tǒng)廣播法牲、默認(rèn)廣播识埋、有序廣播瘫辩、粘性廣播(廢棄)烦秩、App應(yīng)用內(nèi)廣播味悄。
系統(tǒng)廣播和自定義廣播
-
系統(tǒng)廣播
發(fā)送者為系統(tǒng)自己發(fā)送澈缺,注冊和接收的實(shí)現(xiàn)和自定義廣播一致坪创。
為什么要使用自定義廣播而不是自己實(shí)現(xiàn)廣播模式
靜態(tài)注冊和動態(tài)注冊廣播
-
靜態(tài)注冊
常駐,不受任何組件的生命周期影響適用于需要時刻監(jiān)聽的廣播
在xml文件中生命注冊
耗電姐赡,占內(nèi)存
-
定義廣播
class 靜態(tài)廣播注冊():BroadcastReceiver() { override fun onReceive(p0: Context?, p1: Intent?) { Toast.makeText(p0,"廣播接收", Toast.LENGTH_SHORT).show() } }
-
注冊廣播
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"> <application> <receiver android:name=".靜態(tài)廣播注冊" android:enabled="true" <!-- --> android:exported="true" <!-- 是否接收其他應(yīng)用的廣播 --> android:permission="mypermission" <!-- 具有相應(yīng)權(quán)限的發(fā)送者,才能往這個接收者發(fā)送廣播 --> > <intent-filter> <action android:name="MyTest"/> <!-- action --> </intent-filter> </receiver> </application> </manifest>
-
發(fā)送廣播
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) } fun sendBroadcastReceiver(view: View) { tv_sendBroadcastReceiver.setOnClickListener { val intent = Intent() intent.action = "MyTest" intent.putExtra("參數(shù)","參數(shù)值") sendBroadcast(intent) } } }
-
-
動態(tài)注冊
非常駐廣播
在代碼中動態(tài)聲明
跟隨組件生命周期變化
適用于需要特定時刻監(jiān)聽的廣播class MainActivity : AppCompatActivity() { private lateinit var receiver:TestReceiver override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val intentFilter = IntentFilter() intentFilter.addAction("test") receiver = TestReceiver() //動態(tài)注冊廣播 registerReceiver(receiver,intentFilter) } //xml布局中的點(diǎn)擊事件莱预,發(fā)送廣播 fun sendBroadcastReceiver(view: View) { tv_sendBroadcastReceiver.setOnClickListener { val intent = Intent() intent.action = "test" intent.putExtra("參數(shù)","參數(shù)值") sendBroadcast(intent) } } //及時注銷廣播,防止內(nèi)存泄露 override fun onPause() { super.onPause() unregisterReceiver(receiver) //及時注銷廣播项滑,防止內(nèi)存泄露 } class TestReceiver : BroadcastReceiver() { override fun onReceive(p0: Context?, p1: Intent?) { Toast.makeText(p0,"廣播接收",Toast.LENGTH_SHORT).show() } } }
-
動態(tài)注冊在何時注銷比較好
盡量在onResume注冊依沮,在onPause注銷。因?yàn)閛nPause是App死亡前肯定會執(zhí)行的方法。但是當(dāng)系統(tǒng)內(nèi)存不足時危喉,App在執(zhí)行完onPause后就會被銷毀宋渔,來不及執(zhí)行onStop、onDestory方法辜限。
-
系統(tǒng)廣播皇拣、默認(rèn)廣播、有序廣播列粪、粘性廣播(廢棄)审磁、App應(yīng)用內(nèi)廣播
系統(tǒng)廣播
-
默認(rèn)廣播
- 特點(diǎn):
- 所有的接受者之間是異步的
- 接收者相互之間不會有影響
- 接收者無法阻止其他接收者接收
- 優(yōu)先級、setResultExtras(Bundle())岂座、abortBroadcast等有序廣播API的設(shè)置無效
- 特點(diǎn):
-
有序廣播
-
特點(diǎn):
- 通過sendOrderedBroadcast(intent,null)發(fā)送态蒂,第二個參數(shù)為權(quán)限,傳null表示不需要任何權(quán)限
- 根據(jù)優(yōu)先級(-1000到1000)從大到小接收廣播
- 同優(yōu)先級動態(tài)注冊的先接收
- 同優(yōu)先級先注冊的先接收
- 通過xml的intent-filter的priority或者intentFilter.priority=xx指定優(yōu)先級
- 在接收方法onReceive里可以使用setResultExtras(Bundle())設(shè)置下一個接收者的接收到的數(shù)據(jù)
- 在接收方法onReceive里可以使用abortBroadcast終止廣播
- 在接收方法onReceive里可以使用resultData傳遞字符串?dāng)?shù)據(jù)
有序廣播sendOrderedBroadcast(intent,null)的權(quán)限參數(shù):?
-
粘性廣播(廢棄)
-
App應(yīng)用內(nèi)廣播
- 特點(diǎn):
- 廣播不會發(fā)送
- 關(guān)于费什,發(fā)送本地廣播
- 將上面實(shí)現(xiàn)廣播的代碼的注冊钾恢、取消注冊、發(fā)送中的context參數(shù)改為 LocalBroadcastManager.getInstance(this)
- 關(guān)于鸳址,接收時防止惡意接收到特殊構(gòu)造的廣播攻擊:
- 將exported設(shè)置為false瘩蚪,使得只接收本應(yīng)用廣播
- 發(fā)送和接收時,增加權(quán)限字段稿黍,也可防止
- 發(fā)送廣播時通過intent.setPackage(receiverPackageName)指定廣播接收器對應(yīng)的包名
- 特點(diǎn):
onReceive(p0: Context?, p1: Intent?)方法中的Context
- 本地廣播+動態(tài)注冊:Activity Context
- 本地廣播+靜態(tài)注冊:Application Context
- 非本地廣播+動態(tài)注冊:Activity Context
- 非本地廣播+靜態(tài)注冊:ReceiverRestricted Context
onReceive(p0: Context?, p1: Intent?)方法中的Intent
安卓8.0后廣播的改動
- 在AndroidManifest.xml中注冊無效的廣播
- 屏幕的開疹瘦、關(guān)廣播
- 電量的變化廣播
- 等等
- 有序廣播的接收者必須配置優(yōu)先級,防止接收順序錯亂
- 只能通過動態(tài)注冊的方式巡球,實(shí)現(xiàn)有序廣播言沐。
安卓廣播源碼實(shí)現(xiàn)
-
靜態(tài)廣播注冊原理
-
在系統(tǒng)啟動的時候通過PackageManagerService掃描已安裝應(yīng)用進(jìn)行注冊。具體掃描代碼如下:
-