Google大佬都用的广播goAsync源码分析

下面就详细讲解一下“Google大佬都用的广播goAsync源码分析”的完整攻略。

什么是广播goAsync

广播goAsync是Android中一种异步广播处理方式,它可以在主线程之外执行广播接收器的代码,避免了主线程阻塞。在Android系统中,广播是一种重要的机制,它可以在应用程序间传递消息。但是,当广播接收器执行耗时操作时,就会阻塞UI线程,影响用户体验,这时就需要使用广播goAsync来异步处理广播。

广播goAsync的使用方法

使用广播goAsync处理广播的步骤如下:

创建广播接收器

首先需要创建一个广播接收器,在其中实现异步处理逻辑。示例代码如下:

public class MyReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        // 获取异步广播结果回调对象
        final PendingResult pendingResult = goAsync();
        // 在异步线程中处理广播
        new Thread(new Runnable() {
            @Override
            public void run() {
                //处理广播
                //...
                //异步处理完成后调用finish方法,通知系统已经处理完广播
                pendingResult.finish();
            }
        }).start();
    }
}

注册广播接收器

注册广播接收器的方法有两种,一种是在代码中动态注册,另一种是在AndroidManifest.xml文件中静态注册。

动态注册

动态注册广播接收器的示例代码如下:

//创建广播接收器实例
MyReceiver myReceiver = new MyReceiver();
//创建IntentFilter对象
IntentFilter filter = new IntentFilter();
//添加要监听的广播类型
filter.addAction("com.example.broadcast.MY_BROADCAST");
//注册广播接收器
registerReceiver(myReceiver, filter);

静态注册

在AndroidManifest.xml文件中静态注册广播接收器的示例代码如下:

<receiver android:name=".MyReceiver">
    <intent-filter>
        <action android:name="com.example.broadcast.MY_BROADCAST" />
    </intent-filter>
</receiver>

发送广播

发送广播的方法有两种,一种是发送标准广播,另一种是发送有序广播。

发送标准广播

发送标准广播的示例代码如下:

//创建Intent对象
Intent intent = new Intent();
//设置广播类型
intent.setAction("com.example.broadcast.MY_BROADCAST");
//发送标准广播
sendBroadcast(intent);

发送有序广播

发送有序广播的示例代码如下:

//创建Intent对象
Intent intent = new Intent();
//设置广播类型
intent.setAction("com.example.broadcast.MY_BROADCAST");
//发送有序广播
sendOrderedBroadcast(intent, null);

广播goAsync源码分析

为了更好地了解广播goAsync的实现原理,下面对其源码进行分析。

BroadcastReceiver.goAsync

广播接收器的goAsync方法是广播goAsync实现的核心。源码如下:

public final PendingResult goAsync() {
    if (mPendingResult == null) {
        // 创建PendingResult实例
        mPendingResult = new PendingResult(this, mOrderedHint, mInitialSticky, mDebugUnregister);
    }
    return mPendingResult;
}

BroadcastReceiver.PendingResult

PendingResult是广播goAsync的回调接口,它可以在异步线程中执行广播接收器里的代码。PendingResult的实现源码如下:

public static final class PendingResult {
    // 接收器对象
    private final BroadcastReceiver mReceiver;
    // 广播类型(有序广播或标准广播)
    private final String mType;
    // 是否为有序广播
    private final boolean mOrdered;
    // 是否是初次注册
    private final boolean mInitialSticky;
    // 是否为调试模式
    private final boolean mDebug;
    // resultCode,用于广播结果回传
    private int mResultCode;
    // resultData,用于广播结果回传
    private String mResultData;
    // resultExtras,用于广播结果回传
    private Bundle mResultExtras;
    // 意图
    private final Intent mResultAbort;

    public void setResultCode(int code) {
        mResultCode = code;
    }

    public void setResultData(String data) {
        mResultData = data;
    }

    public void setResultExtras(Bundle extras) {
        mResultExtras = extras;
    }

    public void setResult(int code, String data, Bundle extras) {
        mResultCode = code;
        mResultData = data;
        mResultExtras = extras;
    }

    public void abortBroadcast() {
        if (mOrdered) {
            mResultAbort.setFlags(Intent.FLAG_RECEIVER_ABORTED);
        } else {
            throw new RuntimeException("Abort not supported for asynchronous broadcasts");
        }
    }

    public void finish() {
        if (mDebug) {
            Log.i(TAG, "Finished result " + mResultCode + ", data '" + mResultData + "', extras " + mResultExtras);
        }
        final IActivityManager am = ActivityManagerNative.getDefault();
        if (mOrdered) {
            try {
                am.finishReceiver(mReceiver, mResultCode, mResultData, mResultExtras, mResultAbort, mInitialSticky);
            } catch (RemoteException e) {
                // ...
            }
        } else {
            try {
                am.finishReceiver(mReceiver, mResultData, mResultExtras, mInitialSticky);
            } catch (RemoteException e) {
                // ...
            }
        }
    }
}

总结

以上就是“Google大佬都用的广播goAsync源码分析”的完整攻略。广播goAsync是一种在Android系统中用于异步处理广播的机制。使用广播goAsync需要创建一个广播接收器,并在其中实现异步处理逻辑。同时,我们也可以通过阅读源码,更好地了解广播goAsync的实现原理。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Google大佬都用的广播goAsync源码分析 - Python技术站

(0)
上一篇 2023年5月25日
下一篇 2023年5月25日

相关文章

  • Django实现jquery select2带搜索的下拉框

    要实现一个带搜索的下拉框,需要用到Django作为后端框架,同时引入JQuery和Select2插件。下面是详细的步骤: 1. 安装依赖 首先,需要安装以下依赖: Django JQuery Select2 JS和CSS文件可以从官网下载,也可以使用CDN。 2. 定义模型 接下来,需要定义一个模型类,以便在前端显示下拉框列表。例如,若要创建一个学生模型类:…

    人工智能概览 2023年5月25日
    00
  • OpenCV实现车牌定位(C++)

    OpenCV实现车牌定位(C++) 背景介绍 车牌定位是智能交通系统、物流系统等应用中的一个重要的识别环节。本文将介绍基于OpenCV库的车牌定位方法。 环境准备 在运行本文代码前,请确保已经安装以下环境:- OpenCV库- C++编译器 方法介绍 车牌定位主要有以下几个步骤: 1. 车辆图像预处理 车辆图像一般需要经过预处理才能进行车牌定位。预处理包括:…

    人工智能概览 2023年5月25日
    00
  • 详解Django自定义图片和文件上传路径(upload_to)的2种方式

    Sure!下面是“详解Django自定义图片和文件上传路径(upload_to)的2种方式”的完整攻略。 方式1:在models.py中定义upload_to参数 在Django中,通常使用FileField或者ImageField来上传文件或者图片。这类字段包含一个upload_to参数,你可以指定这个参数来上传到自定义的路径。下面是示例代码: from …

    人工智能概览 2023年5月25日
    00
  • Epson(1640XL)扫描仪软故障一例-Epson Scan无法启动

    针对“Epson(1640XL)扫描仪软故障一例-Epson Scan无法启动”这个问题,我们可以采取以下步骤来进行解决: 1. 清理Epson Scan软件及相关驱动程序 首先,我们需要彻底删除Epson Scan软件以及相关的驱动程序。具体步骤如下: 打开控制面板,点击“程序和功能”,在程序列表中找到Epson Scan及相关驱动程序,选择卸载。 在卸载…

    人工智能概览 2023年5月25日
    00
  • 在lnmp环境中的nginx编译安装

    在 LNMP 环境中安装 Nginx 的步骤大概如下: 1. 安装编译工具 在 Linux 中编译 Nginx 需要用到一些编译工具,比如 gcc、make 等,可以通过以下命令安装: yum -y install gcc make pcre pcre-devel zlib zlib-devel openssl openssl-devel 2. 下载并解压 …

    人工智能概览 2023年5月25日
    00
  • 浅谈多卡服务器下隐藏部分 GPU 和 TensorFlow 的显存使用设置

    标题 浅谈多卡服务器下隐藏部分 GPU 和 TensorFlow 的显存使用设置 背景 在使用多卡服务器进行模型训练时,由于显存限制,可能会出现一部分 GPU 显存不足无法使用,或者需要提前将一些 GPU 预留出来供其他程序使用的情况。本文将提供一些方法来解决这种情况下的显存使用问题。 方案 1. 隐藏部分 GPU 在 Linux 系统下,我们可以使用 CU…

    人工智能概论 2023年5月25日
    00
  • Python如何读取相对路径文件

    下面我将针对Python如何读取相对路径文件给出详细讲解的攻略。 什么是相对路径? 在计算机文件系统中,相对路径是指从当前目录到目标文件或目录的路径。相对路径的最常见情况是从当前工作目录开始的。 例如,在Windows操作系统中,如果当前工作目录为D:/Projects,那么相对路径./data.txt将引用位于D:/Projects/data.txt的文件…

    人工智能概览 2023年5月25日
    00
  • Python用GET方法上传文件

    使用GET方法上传文件在HTTP协议中是不符合规范的。一般来说,上传文件应该使用POST方法或PUT方法。而在Python中使用GET方法上传文件也是不建议的。以下是使用Python通过POST方法上传文件的完整攻略: 1. 准备上传文件和服务器接口 首先,我们需要准备好要上传的文件,以及服务端接口。为了方便演示,我们可以先创建一个本地的测试文件,并搭建一个…

    人工智能概论 2023年5月25日
    00
合作推广
合作推广
分享本页
返回顶部