[Android 四大组件] --- BroadcastReceiver

简介: [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页面收广播

//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);
    }
}
// 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中注册

<receiver android:name="com.example.myapplication.StaticBRReceiver">
            <intent-filter>
                <action android:name="com.example.broadcasttest.StaticBRReceiver" />
            </intent-filter>
        </receiver>
// 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);
            }
        });
    }
}
// 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方法

// 特点:

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

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

// 应用场景:

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

目录
相关文章
|
3月前
|
Android开发 开发者
什么是Android Jetpack,它包括哪些组件?
什么是Android Jetpack,它包括哪些组件?
42 0
|
15天前
|
存储 数据库 Android开发
构建高效安卓应用:采用Jetpack架构组件优化用户体验
【4月更文挑战第12天】 在当今快速发展的数字时代,Android 应用程序的流畅性与响应速度对用户满意度至关重要。为提高应用性能并降低维护成本,开发者需寻求先进的技术解决方案。本文将探讨如何利用 Android Jetpack 中的架构组件 — 如 LiveData、ViewModel 和 Room — 来构建高质量的安卓应用。通过具体实施案例分析,我们将展示这些组件如何协同工作以实现数据持久化、界面与逻辑分离,以及确保数据的即时更新,从而优化用户体验并提升应用的可维护性和可测试性。
|
2月前
|
数据可视化 Android开发
[Android 四大组件] --- Service
[Android 四大组件] --- Service
24 0
|
2月前
|
Android开发
[Android 四大组件] --- Activity
[Android 四大组件] --- Activity
22 1
|
2月前
|
存储 数据库 Android开发
安卓四大组件是什么?
安卓四大组件是什么?
|
3月前
|
数据库 Android开发 开发者
Android基础知识:什么是Android应用的四大组件?
Android基础知识:什么是Android应用的四大组件?
62 1
|
6天前
|
Linux 编译器 Android开发
FFmpeg开发笔记(九)Linux交叉编译Android的x265库
在Linux环境下,本文指导如何交叉编译x265的so库以适应Android。首先,需安装cmake和下载android-ndk-r21e。接着,下载x265源码,修改crosscompile.cmake的编译器设置。配置x265源码,使用指定的NDK路径,并在配置界面修改相关选项。随后,修改编译规则,编译并安装x265,调整pc描述文件并更新PKG_CONFIG_PATH。最后,修改FFmpeg配置脚本启用x265支持,编译安装FFmpeg,将生成的so文件导入Android工程,调整gradle配置以确保顺利运行。
24 1
FFmpeg开发笔记(九)Linux交叉编译Android的x265库
|
28天前
|
Java Android开发
Android 开发获取通知栏权限时会出现两个应用图标
Android 开发获取通知栏权限时会出现两个应用图标
14 0
|
3天前
|
数据库 Android开发 开发者
安卓应用开发:构建高效用户界面的策略
【4月更文挑战第24天】 在竞争激烈的移动应用市场中,一个流畅且响应迅速的用户界面(UI)是吸引和保留用户的关键。针对安卓平台,开发者面临着多样化的设备和系统版本,这增加了构建高效UI的复杂性。本文将深入分析安卓平台上构建高效用户界面的最佳实践,包括布局优化、资源管理和绘制性能的考量,旨在为开发者提供实用的技术指南,帮助他们创建更流畅的用户体验。