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

// 特点:

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

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

// 应用场景:

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

相关推荐
xvch1 小时前
Kotlin 2.1.0 入门教程(二十五)类型擦除
android·kotlin
simplepeng10 小时前
我的天,我真是和androidx的字体加载杠上了
android
小猫猫猫◍˃ᵕ˂◍11 小时前
备忘录模式:快速恢复原始数据
android·java·备忘录模式
CYRUS_STUDIO13 小时前
使用 AndroidNativeEmu 调用 JNI 函数
android·逆向·汇编语言
梦否13 小时前
【Android】类加载器&热修复-随记
android
徒步青云13 小时前
Java内存模型
android
今阳14 小时前
鸿蒙开发笔记-6-装饰器之@Require装饰器,@Reusable装饰器
android·app·harmonyos
-优势在我18 小时前
Android TabLayout 实现随意控制item之间的间距
android·java·ui
hedalei18 小时前
android13修改系统Launcher不跟随重力感应旋转
android·launcher
Indoraptor20 小时前
Android Fence 同步框架
android