首页 > 其他分享 >BroadcastReceiver 广播-Android四大组件 一文精讲

BroadcastReceiver 广播-Android四大组件 一文精讲

时间:2024-09-03 19:53:36浏览次数:14  
标签:val 精讲 action 广播 intent fun Intent Android BroadcastReceiver

目录

1.广播用途与机制

1.1什么时候用broadcast?

1.2原理图解

2.注册广播

2.1静态注册

2.2动态注册

2.3二者区别与联系

同:

异:

3.接受广播

3.1接收系统广播

3.2接收自定义附带值广播

4.发送自定义广播

4.1发送无序广播

4.2发送有序广播

4.3发送应用程序内部广播


1.广播用途与机制

1.1什么时候用broadcast?

  • 在应用程序之间或同一应用程序之间传递消息(系统级)
  • 可以获取系统发出的消息
  • 利用广播在应用内发送消息(可携带数据)

1.2原理图解


2.注册广播

2.1静态注册

AndroidManifest.xml文件中注册

<receiver android:name=".MyBroadcastReceiver">
    <intent-filter>
        <action android:name="com.example.ACTION_MY_BROADCAST" />
    </intent-filter>
</receiver>

2.2动态注册

  • 实现BroadCastReceiver,可匿名实现
  • 实现IntentFillter,设置需要接受的广播TAG
  • 在界面onCreate()中调用registerReceiver(BroadCastReceiver,IntentFillter)
  • 在界面onDestroy()中调用unregisterReceiver(BroadCastReceiver)手动销毁!!!
class MainActivity : AppCompatActivity() {

    private lateinit var receiver: BroadcastReceiver

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        receiver = object : BroadcastReceiver() {
            override fun onReceive(context: Context?, intent: Intent?) {
                //TODO
                }
            }
        }

        val filter = IntentFilter().apply{
                       addAction(Intent.ACTION_BATTERY_CHANGED)//获取系统电量广播
                     }
        registerReceiver(receiver, filter)
    }

    override fun onDestroy() {
        super.onDestroy()
        unregisterReceiver(receiver)
    }
}

2.3二者区别与联系

同:

应用程序之间或内部,对外部过滤后的信息,进行接收和发送的机制

异:

  • 静态注册与App进程无关,系统存货,广播一直打开
  • 动态注册依赖注册的界面,界面销毁就要注册广播

3.接受广播

3.1接收系统广播

在AndroidManifesft中申请权限才能接受系统广播,比如:

//开机启动广播
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
//电量变化广播
<uses-permission android:name="android.permission.BATTERY_STATS" />
//网络变化广播
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

在重写的Receiver方法中调用intent.getIntExtra或getStringExtra等其他方法,如:

override fun onReceive(context:Context?,intent:Intent?){
    val level = intent?.getIntExtra(BatteryManager.EXTRA_LEVEL,0)
    level?.apply{
        Log.d("TAG","电池电量: $this")  
    }
}

3.2接收自定义附带值广播

override fun onReceive(context:Context?,intent:Intent?){
    val str = intent?.getStringExtra(发送广播时设置的name) //通过name相同获取value
    if(context != null && intent != null) Log.d(TAG,"获取 $str")
}


4.发送自定义广播

4.1发送无序广播

  • 为Intent设置自定义的action名字
  • 可以同时调用putExtra(name,value)设置附带值,后续通过name接受value
  • 由sendBroadcast(Intent)向所有action相同接收者,发送这个intent
  • 完全异步执行,各action相同接收器的接受顺序不一定
fun send(){
    val intent = Intent().apply{
        action = "hxl"
        putExtra("zj","798")
    }
    sendBroadcast(intent)
}

当然获取如3.2接受自定义广播,代码如下:

//在Activity或者Fragment中
fun register(){
    val intentFillter = IntentFillter().apply{
        addAction("hxl")
    }
    registerReceiver(MyBroadcastReceiver(),intentFillter)
}


class MyBroadcastReceiver:BroadcastReceiver(){
    override fun onReceive(context:Context?,intent:Intent?){
        val str = intent?.getStringExtra("zj") //通过name相同获取value
        if(context != null && intent != null) Log.d(TAG,"获取 $str")//LOG打印值为798
        
    }
}

4.2发送有序广播

  • 在发送广播时,设置IntentFillter的priority属性,其值越高,优先级越高
  • 发送时调用sendOrderBroadcast(intent,null)而不是sendBroadcast方法
  • 有序广播可以由优先级高的先获取,然后依次传递给优先级较低的
  • 优先级高的广播接收者调用abortBroadcast截断广播,后续接收者收不到该action值的广播
companion object{
    private const val action = "zhoujun_MSG"
}

fun register(broadCastReceiver:BroadcastReceiver,aPriority:Int){
    val intentFillter = IntentFillter().apply{
         addAction(action)
         priority = aPriority  
    }
    sendOrderBroadcast(broadcastReceiver,intentFillter)
}

//在onCreate中,只能获取到
register(object: BroadcastReceiver(){
    override fun onReceive(context:Context?,intent:Intent?){
        Log.d(TAG,"A获取") 
        aborBroadcast()         //方法一
    }
},100)//优先级为100

register(object: BroadcastReceiver(){
    override fun onReceive(context:Context?,intent:Intent?){
        aborBroadcast()         //方法二
        Log.d(TAG,"B获取")
    }
},10)//优先级为10

register(object: BroadcastReceiver(){
    override fun onReceive(context:Context?,intent:Intent?){
        Log.d(TAG,"C获取")
    }
},1)//优先级为1

结果只有A获取被LOG打印出来,说明广播在优先级为100处被截断

图中由两处调用aborBroadcast(),实际在A除被截断,B出也就没执行

4.3发送应用程序内部广播

BroadcastReceiver 在设计之初,就是想从全局的角度去设计一个方便不同应用程序之间进行通信的组件

而这样的一个开放的设计,对单个应用程序而言,BroadcastReceiver 是存在各种安全问题的

LocalBroadcast 就是为了在同一个应用程序内,进行通信的组件

//在Activity中
val manager by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED){
    localBroadcastReceiver.getInstance(this)
}

val myBroadcastReceiver by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED){
    MyBroadcastReceiver()
}

companion object{
    private const val action = "example"
}

//onCreate中调用
fun register(){
    val intentFillter = IntentFillter().apply{
         addAction(action)
    }
    manager.registerReceiver(myBroadcastReceiver,intentFillter)
}

//发送广播时调用
fun send(){
    val intent = Intent().apply{
        action = action 
   }
    manager.sendBroadcast(intent)
}

//onDestroy中调用
fun unregister(){
    manager.unregisterReceiver(myBroadcastReceiver)
}

  • 先通过懒加载机制生成LocalBroadcastReceiver单例对象
  • 这个单例对象有本身的registerReceiver和sendBroadcast和unregisterReceiver方法

标签:val,精讲,action,广播,intent,fun,Intent,Android,BroadcastReceiver
From: https://blog.csdn.net/m0_74837900/article/details/141818034

相关文章

  • Android开发 - BitmapFactory 类解码图像文件并转换为 Bitmap 对象与 BitmapFactory.O
    BitmapFactory是什么BitmapFactory用于解码图像文件,并将它们转换为Bitmap对象。Bitmap是用来表示图像的基本类,它是一个位图的抽象表示。BitmapFactory提供了一组静态方法,这些方法可以用来将各种图像文件格式(如PNG、JPEG、WEBP等)解码成Bitmap对象BitmapFactory的好......
  • Android经典实战之窗口和WindowManager
    本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点在Android开发中,“窗口”是一个非常基础且重要的概念。窗口通常用于承载和显示用户界面内容。了解窗口的工作机制,以及如何管理窗口,对于开发复杂的和用户体验良好的应用程序至......
  • Android Activity启动过程全解析
     https://blog.csdn.net/tenggangren/article/details/50925740 App与AMS通过Binder进行IPC通信,AMS(SystemServer进程)与zygote通过Socket进行IPC通信。一个App的程序入口到底是什么?是ActivityThread.main()。 1.ActivityManagerServices,简称AMS,服务端对象,负责系统中所有A......
  • Android UI绘制流程
     UI绘制流程,Activity、Dialog、PopupWindow等--android系统的事件分发流程分为很多部分: Native层–>ViewRootImpl层–>DecorView层–>Activity层–>ViewGroup层–>View层。  其实Toast窗口和Activity、Dialog、PopupWindow有一个不太一样的地方,就是Toast窗......
  • 基于ssm+vue基于Android的考研咨询APP的设计与实现【开题+程序+论文】
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着高等教育的普及和就业竞争的日益激烈,越来越多的学生选择继续深造,其中考研成为了众多学子的首选之路。然而,考研之路并非坦途,它要求考生具备扎实的......
  • 基于ssm+vue基于Android开发的智能音乐播放系统【开题+程序+论文】
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景在数字化时代背景下,音乐已成为人们日常生活中不可或缺的一部分,它不仅能够调节情绪、缓解压力,还能丰富我们的精神世界。随着移动互联网技术的飞速发展......
  • Android设备之间UVC Gadget bulk模式无法正常打开问题
    平台:RK3588Android版本:12内核版本:Linux5.10.66问题:通过usbgadget枚举uvc设备后,使用bulk传输,连接windowsPC可用正常打开预览,连接到另外AndroidHost设备无法正常打开。如果使用isochronous方式传输则都正常。分析:连接到PC(windows)上可以正常出图,但是连接到另外一个RK3588设......
  • Android架构组件:MVVM模式的实战应用与数据绑定技巧
    Android应用开发已经逐渐变得高效且模块化,MVVM(Model-View-ViewModel)设计模式与Android架构组件的结合,无疑提升了开发者的生产力。在本指南中,我们将详细介绍MVVM模式的概念,如何在Android中实现MVVM,并结合实际操作案例让读者更好地理解与运用数据绑定技巧。1.MVVM模式......
  • Android Glide加载图片时,基于图片宽高比自动伸缩ImageView高度
    ImageView布局<ImageViewandroid:id="@+id/iv"android:layout_width="match_parent"android:layout_height="wrap_content"/>代码实现GlideUtil.java/***加载图片,支持高度伸缩*@paramcontext上下文......
  • Android协程的使用场景
    importkotlinx.coroutines.Dispatchersimportkotlinx.coroutines.delayimportkotlinx.coroutines.withContextsuspendfunallPlants():List<Plant>=withContext(Dispatchers.Default){delay(1500)valresult=sunflowerService.getA......