[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方法

// 特点:

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

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

// 应用场景:

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

相关推荐
千里马学框架1 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台1 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone1 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc1 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo1 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077001 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼1 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone1 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen1 天前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone1 天前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui