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

// 特点:

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

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

// 应用场景:

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

相关推荐
兰琛2 小时前
Compose组件转换XML布局
android·xml·kotlin
水w4 小时前
【Android Studio】解决报错问题Algorithm HmacPBESHA256 not available
android·开发语言·android studio
隐-梵6 小时前
Android studio进阶教程之(二)--如何导入高德地图
android·ide·android studio
Kika写代码6 小时前
【Android】界面布局-线性布局LinearLayout-例子
android·gitee
wangz767 小时前
kotlin,jetpack compose,使用DataStore保存数据,让程序下次启动时自动获取
android·kotlin·datastore·jetpack compose
Thread.sleep(0)8 小时前
WebRTC源码解析:Android如何渲染画面
android·webrtc
Android 小码峰啊9 小时前
Android Dagger 2 框架的注解模块深入剖析 (一)
android·adb·android studio·android-studio·androidx·android runtime
Android 小码峰啊10 小时前
Android Fresco 框架缓存模块源码深度剖析(二)
android
大胃粥12 小时前
Android V app 冷启动(8) 动画结束
android
ufo00l12 小时前
Kotlin在Android中有哪些重要的应用和知识点是需要学习或者重点关注的
android