介绍
广播接收者是Android的四大组件,与其他组件不同,广播接收者可以动态注册,用于接收到广播后处理,也可起着进程间通信作用,了解到Android用多种通信方式,那为什么还要搞个广播接收者让我们学呢?
广播机制有着牢固的地位,广播接收者和发送者是无需知道对方的存在和位置,使用简单,使得应用程序高内聚低耦合,简化代码,降低使用风险,减少维护工作。
生命周期注意事项:
广播的生命周期极其短暂,最好不要做耗时操作,超过10s会弹出ANR,而且在如果是动态注册,则必须在Activity销毁前使用unregisterReceiver注销广播,否则报异常
使用方法
静态注册
1、继承BroadcastReceiver,重写onReceive()
class MyBroadcastReceiver: BroadcastReceiver() {override fun onReceive(context: Context?, intent: Intent?) {Log.i(\"receiver\",intent?.getStringExtra(\"msg\"))}}
2、清单文件:
<receiver android:name=\".MyBroadcastReceiver\"><intent-filter><action android:name=\"android.intent.action.MyBroadcast\"></action></intent-filter></receiver>
动态注册
class MainActivity : AppCompatActivity() {var myBroadcastReceiver:MyBroadcastReceiver? = MyBroadcastReceiver()override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)val filter = IntentFilter()filter.addAction(\"android.intent.action.MyBroadcast\")registerReceiver(myBroadcastReceiver, filter)}override fun onDestroy() {unregisterReceiver(myBroadcastReceiver)myBroadcastReceiver = nullsuper.onDestroy()}}
两种注册方式区别:
- 静态注册的广播运行一次后,就一直会处于广播接收状态,即使应用程序退出。
- 动态注册无需再清单文件写,注销后就不能再接收广播了。
- 如果是静态注册的广播,context为ReceiverRestrictedContext,所在如果在这里要启动一个Activity的话(调用startActivity),需要在intent中添加Intent.FLAG_ACTIVITY_NEW_TASK;
- 如果是动态注册,registerReceiver是android.content.ContextWrapper类中的方法,Activity 和Service都继承了ContextWrapper,所以可以直接调用。
特殊的广播接收者:
频繁发广播的需要动态注册,如锁屏,电量变化,网络连接,如果是静态注册会无效。
发送广播
1. 无序广播
val intent = Intent(\"android.intent.action.MyBroadcast\")intent.putExtra(\"msg\", \"普通广播\")sendBroadcast(intent)
2. 有序广播
需要在intent-filter里设置优先级
静态广播需要再清单文件设置:
<receiver android:name=\".MyBroadcastReceiver\"><intent-filter android:priority=\"100\"><action android:name=\"android.intent.action.MyBroadcast\"></action></intent-filter></receiver><receiver android:name=\".MyBroadcastReceiver2\"><intent-filter android:priority=\"50\"><action android:name=\"android.intent.action.MyBroadcast\"></action></intent-filter></receiver>
动态注册的这样设置:
filter.setPriority(100);
数字越大优先级越高,同优先级的广播接收者,动态优先于静态
发送:
val intent = Intent(\"android.intent.action.MyBroadcast\")intent.putExtra(\"msg\", \"有序\")sendOrderedBroadcast(intent,null);
之后即可在自个儿广播接收者拦截:
class MyBroadcastReceiver: BroadcastReceiver() {override fun onReceive(context: Context?, intent: Intent?) {Log.i(\"receiver\",intent?.getStringExtra(\"msg\"))abortBroadcast()resultData = \"有序广播版本2\"}}
可见MyBroadcastReceiver拦截后修改了resultData,之后广播继续往下传递,只不过传到另一个广播接收者的参数变成了\”有序广播版本2\”。