一、介绍注:本文中代码部分使用Kotlin语言进行编写
广播分为两个方面: 广播发送者和广播接收者(broadcastReceiver)
广播类型:
1. 标准广播(normal broadcasts): 是一种完全异步执行的广播,在广播发出去之后,所有的broadcastReceiver几乎会在同一时刻收到这条广播。所以对于broadcastReceiver来说它们没有顺序可言。这种广播效率高,但也无法被截断。
2. 有序广播(ordered broadcasts): 同步执行广播,在广播发出去之后同一时刻只会有一个broadcastReceiver接收到广播,当这个broadcastReceiver中的逻辑执行完之后才会继续传递。所以,对于broadcastReceiver来说是有先后顺序之分的,优先级高的broadcastReceiver先接受到广播,优先级低的broadcastReceiver后接收到广播,并且broadcastReceiver还可以截断广播,使优先级低于当前broadcastReceiver的broadcastReceiver无法接收到广播。
使用场景:
同一app内部的同一组件内的消息通信(单个或多个线程之间)
同一app内部的不同组件之间的消息通信(单个进程)
同一app具有多个进程的不同组件之间的消息通信
不同app之间的组件之间消息通信AndroID系统在特定情况下与App之间的消息通信。
2.1 静态广播以接收开机广播为例broadcastReceiver在使用时要先进行注册,注册broadcastReceiver的方式一般分为静态注册(在AndroIDManifest.xml中注册)、动态注册(在代码中注册)。静态注册可以让程序在未启动的状态下也能接收广播,而动态注册则只能在程序启动之后才能接收广播。
新建broadcastReceiver,右键点击含有主类的包,New->Other->broadcast Receiver,
class MyReceiver : broadcastReceiver() { overrIDe fun onReceive(context: Context, intent: Intent) { Toast.makeText(context,"成功接收开机广播",Toast.LENGTH_LONG).show() }}
注:broadcastReceiver中是不允许开启线程的,当onReceive()方法运行较长时间时,程序会报错,不建议添加过多的逻辑及耗时间的 *** 作
在AndroIDManifest.xml
中注册,其中enabled
属性表示表示是否启用这个broadcastReceiver,exported
属性表示是否允许broadcastReceiver接收本程序外的广播
<receiver androID:name=".MyReceiver" androID:enabled="true" androID:exported="true"></receiver>
在receiver
标签中添加一个intent-filter
标签,使broadcastReceiver可以接受开机广播
<receiver androID:name=".MyReceiver" androID:enabled="true" androID:exported="true"> <intent-filter> <action androID:name="androID.intent.action.BOOT_COMPLETED"/> </intent-filter> </receiver>
为了保证用户隐私,接收开机广播需要使用系统权限,在AndroIDManifest.xml
中声明系统权限(在application上方声明)
<uses-permission androID:name="androID.permission.RECEIVE_BOOT_COMPLETED"/>
2.2 自定义广播2.2.1 标准广播创建一个broadcastReceiver来接收广播,参考上述静态广播中的创建方法
class MyReceiver : broadcastReceiver() { overrIDe fun onReceive(context: Context, intent: Intent) { Toast.makeText(context,"成功接收开机广播",Toast.LENGTH_LONG).show() }}
在receiver
标签中添加一个intent-filter
标签,使broadcastReceiver可以接受自定义广播广播
<intent-filter> <action androID:name="com.example.broadcastrecevIErtext.MY_broADCAST"/> </intent-filter>
在activity_main.xml
中添加代码,创建一个按钮作为触发点
<button androID:ID="@+ID/button" androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" androID:text="button" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintleft_toleftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constrainttop_totopOf="parent" />
给按钮设置点击监听事件
button.setonClickListener { //新建一个Intent对象,并将要发送的广播的值传入 val intent = Intent("com.example.broadcastrecevIErtext.MY_broADCAST") //将当前应用程序的包名传给intent intent.setPackage(packagename) //发送广播 sendbroadcast(intent) }
注:Android8.0系统之后,静态注册的broadcastReceiver是无法接受隐式广播的,默认情况下我们创建的自定义广播均为隐式广播,所以要调用setPackage()方法指定广播要发给那个应用程序,从而将广播设置为显式广播
运行程序,点击按钮即可发送广播,在broadcastReceiver接受到广播时将会执行我们编写的逻辑Toast.makeText(context,"成功接收开机广播",Toast.LENGTH_LONG).show()
2.2.2 有序广播由于广播是使用Intent来发送的,所以我们还可以在发送广播的同时携带数据传递给相应的broadcastReceiver
有序广播式一种同步执行广播,并且可以被截断
再创建一个broadcastReceiver,新建MyReceiver_2
class MyReceiver_2 : broadcastReceiver() { overrIDe fun onReceive(context: Context, intent: Intent) { Toast.makeText(context,"MyReceiver_2成功接收开机广播", Toast.LENGTH_LONG).show() }}
修改AndroIDManifest.xml
中代码,使两个broadcastReceiver监听同一条广播
<receiver androID:name=".MyReceiver_2" androID:enabled="true" androID:exported="true"> <intent-filter> <action androID:name="com.example.broadcastrecevIErtext.MY_broADCAST" /> </intent-filter> </receiver>
**运行程序可以看到分别d出两条提示信息
成功接收开机广播
MyReceiver_2成功接收开机广播
修改按钮监听事件的代码
button.setonClickListener { //新建一个Intent对象,并将要发送的广播的值传入 val intent = Intent("com.example.broadcastrecevIErtext.MY_broADCAST") //将当前应用程序的包名传给intent intent.setPackage(packagename) //发送有序广播 sendOrderedbroadcast(intent,null) }
添加代码androID:priority="100"
,将MyReceiver
的优先级设置为100,保证MyReceiver的优先级高于MyReceiver_2
<receiver androID:name=".MyReceiver_2" androID:enabled="true" androID:exported="true"> <intent-filter> <action androID:name="com.example.broadcastrecevIErtext.MY_broADCAST" /> </intent-filter> </receiver> <receiver androID:name=".MyReceiver" androID:enabled="true" androID:exported="true"> <intent-filter androID:priority="100"> <action androID:name="com.example.broadcastrecevIErtext.MY_broADCAST" /> </intent-filter> </receiver>
修改 MyReceiver
中的代码,将广播截断
class MyReceiver : broadcastReceiver() { overrIDe fun onReceive(context: Context, intent: Intent) { Toast.makeText(context,"MyReceiver成功接收开机广播",Toast.LENGTH_LONG).show() //将广播截断 abortbroadcast() }}
运行程序可以看到只会d出MyReceiver
中设置的提示信息
成功接收开机广播
使用sendOrderedbroadcast()
方法,将广播设置为有序广播,并且MyReceiver
的优先级比MyReceiver_2
高,所以MyReceiver
先接收到广播,MyReceiver_2
后接收广播,但是MyReceiver
中使用abortbroadcast()
方法将广播截断,所以MyReceiver_2
无法接收到广播
以上是内存溢出为你收集整理的Android中的BroadcastReceiver全部内容,希望文章能够帮你解决Android中的BroadcastReceiver所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)