[Android 四大组件] --- BroadcastReceiver

1 BroadcastReceiver是什么

BroadcastReceiver(广播接收器)即广播,是一个全局的监听器。

Android 广播分为两个角色:广播发送者、广播接受者。

2 广播类型

广播按照类型分为两种,一种是全局广播,另一种是本地广播

全局广播:就是发出的广播被其他任意应用程序接收,或者可以接收来自其他任意应用程序的广播。

本地广播:则是只能在应用程序内部进行传递的广播,广播接收器也只能接收内部的广播,不能接收其他应用程序的广播

广播按照机制分两种,一种是标准广播,一种是有序广播

标准广播:是一种异步的方式来进行传播的,所有接收者都会接收事件,不可以被拦截,不可以被修改

有序广播:是一种同步执行的广播,按照优先级,一级一级的向下传递,接收者可以修改广播数据,也可以终止广播事件。

3 BroadcastReceiver原理

// 模型

基于消息的发布/订阅事件模型,使用了设计模式中的观察者模式;

// 模型角色:

1.消息订阅者

2.消息发布者

3.消息中心(AMS,即Activity Manager Service)

// 原理描述

1.广播接收者 通过Binder机制在AMS注册

2.广播发送者 通过Binder机制向AMS发送广播

3.AMS根据广播发送者要求,在已注册列表中,寻找合适的广播接收者(寻找依据:IntentFilter/Permission)

4.AMS将广播发送到合适的广播接收者相应的消息循环队列中

5.广播接收者通过消息循环拿到此广播,并回调onReceive()

4 动态注册

给出一个示例:用BroadcastReceiver实现2个activity之间的通信,点击A页面,跳转到B页面,在B页面发送广播,A页面收广播

java 复制代码
//AActivity.java
package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;


import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;

import androidx.annotation.Nullable;


public class AActivity extends AppCompatActivity {
    private DynamicBRReceiver dynamicBRReceiver;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.a_activity_layout);
        // 动态注册广播接收器
        dynamicBRReceiver = new DynamicBRReceiver();
        IntentFilter itFilter = new IntentFilter();
        itFilter.addAction("com.example.broadcasttest.DynamicBRReceiver");
        registerReceiver(dynamicBRReceiver, itFilter);

        findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(AActivity.this, BActivity.class);
                startActivity(intent);
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(dynamicBRReceiver);
    }
}
java 复制代码
// BActivity.java

package com.example.myapplication;

import android.content.ComponentName;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

public class BActivity extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.b_activity_layout);

        findViewById(R.id.btn_send).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //发送广播
                // 动态注册方式发送
                Intent intent = new Intent("com.example.broadcasttest.DynamicBRReceiver");
                sendBroadcast(intent);
            }
        });
    }
}
```java
// DynamicBRReceiver.java
package com.example.myapplication;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;

public class DynamicBRReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "DynamicBRReceiver: 收到广播!!!", Toast.LENGTH_SHORT).show();
    }
}

注意:

1.广播接收器接收到相应广播后,会自动回调onReceive方法

2.一般情况下,onReceive方法会涉及与其它组件之间的交互,如发送Notification、启动Service

3.默认情况下,广播接收器运行在UI线程,因此onReceive方法不能执行耗时操作,否则将导致ANR。

5 静态注册

静态注册的方式需要在AndroidManifest.xml中注册

xml 复制代码
        <receiver android:name="com.example.myapplication.StaticBRReceiver">
            <intent-filter>
                <action android:name="com.example.broadcasttest.StaticBRReceiver" />
            </intent-filter>
        </receiver>
java 复制代码
// BActivity.java

package com.example.myapplication;

import android.content.ComponentName;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

public class BActivity extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.b_activity_layout);

        findViewById(R.id.btn_send).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 静态注册方式发送
                Intent intent = new Intent();
                intent.setComponent(new ComponentName(BActivity.this, StaticBRReceiver.class));
                sendBroadcast(intent);
            }
        });
    }
}
java 复制代码
// StaticBRReceiver.java
package com.example.myapplication;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;

// 静态注册
public class StaticBRReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "StaticBRReceiver: 收到广播!!!", Toast.LENGTH_SHORT).show();
    }
}

6 动态注册和静态注册的区别

// 使用方式:

静态注册是在AndroidManifest文件中使用receiver标签注册的,动态注册是在代码中调用Context.registerReceiver方法

// 特点:

静态注册是常驻广播,不受任何组件的生命周期影响(应用程序关闭后,依旧可以会被系统调用),缺点是耗电,占内存

动态注册是非常驻广播,灵活,跟随组件的生命周期变化(组件结束=广播结束,在组件结束之前必须移除广播接收器)

// 应用场景:

当需要时刻监听广播时,使用静态注册方式;当只需要在特定时刻监说明听广播时,使用动态注册的方式

相关推荐
alexhilton8 小时前
Compose中初始加载逻辑究竟应该放在哪里?
android·kotlin·android jetpack
zh_xuan9 小时前
启动RN服务端口被占用
android·react native
Code-keys11 小时前
Android Codec2 Filter 算法模块开发指南
android·算法·音视频·视频编解码
y = xⁿ12 小时前
MySQL:count(1)与count(*)有什么区别,深分页问题
android·数据库·mysql
程序员陆业聪14 小时前
Android启动全景图:一次冷启动背后到底发生了什么
android
安卓程序员_谢伟光16 小时前
m3颜色定义
android·compose
麻辣璐璐17 小时前
EditText属性运用之适配RTL语言和LTR语言的输入习惯
android·xml·java·开发语言·安卓
北京自在科技17 小时前
谷歌 Find Hub 网页端全面升级:电脑可直接管理追踪器与耳机
android·ios·安卓·findmy
Rush-Rabbit17 小时前
魅族21Pro刷ColorOS16.0操作步骤
android
爪洼传承人17 小时前
AI工具MCP的配置,慢sql优化
android·数据库·sql