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

目录

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方法
  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值