Android ActivityResultLauncher 跨类使用教程

android activityresultlauncher 跨类使用教程

本文详细介绍了在 Android 应用中如何实现 `registerForActivityResult` 的跨类调用。当 `ActivityResultLauncher` 实例在主 Activity 中注册后,若需在其他类中触发其 `launch()` 方法,核心策略是将已注册的 `ActivityResultLauncher` 实例作为参数传递给目标类或方法。文章通过具体代码示例,演示了两种实现方式:构造函数注入和方法参数传递,旨在帮助开发者构建更灵活、解耦的 Android 组件交互逻辑。

registerForActivityResult 是 Android Jetpack 库中用于替代旧版 startActivityForResult() 的现代 API,它提供了一种更安全、更易于管理的方式来处理 Activity 间的结果回调。通常,我们会在 Activity 或 Fragment 的 onCreate() 或 onCreateView() 方法中注册一个 ActivityResultLauncher 实例,并在需要时通过调用其 launch() 方法来启动一个 Activity 并等待结果。然而,当业务逻辑变得复杂,我们需要在 MainActivity 之外的其他辅助类或模块中触发这个 launch() 操作时,如何有效地传递和使用 ActivityResultLauncher 实例就成了一个常见问题

核心概念:传递 ActivityResultLauncher 实例

ActivityResultLauncher 实例在 Activity 或 Fragment 中注册并与宿主的生命周期绑定。它并非一个静态或全局可访问的对象,因此,若要在其他类中调用其 launch() 方法,最直接且推荐的方式就是将这个已注册的实例作为参数,显式地传递给需要使用它的目标类或方法。这符合面向对象编程中的依赖注入原则,有助于保持代码的解耦性和可测试性。

下面将介绍两种主要的实现方式。

实现方式一:通过构造函数注入

这种方法适用于那些需要长期持有 ActivityResultLauncher 实例的辅助类。我们将 ActivityResultLauncher 作为构造函数的参数传递给辅助类,使其能够在自己的方法中调用 launch()。

1. 定义辅助类 (例如 FilePickerHelper)

创建一个辅助类来封装文件选择的逻辑。它将通过构造函数接收 ActivityResultLauncher 实例。

import android.content.Intent;import androidx.activity.result.ActivityResultLauncher;import androidx.activity.result.contract.ActivityResultContracts;/** * 辅助类,用于封装文件选择逻辑,并利用传入的 ActivityResultLauncher 启动文件选择器。 */public class FilePickerHelper {    private final ActivityResultLauncher launcher;    /**     * 构造函数,注入 ActivityResultLauncher 实例。     * @param launcher 已注册的 ActivityResultLauncher 实例。     */    public FilePickerHelper(ActivityResultLauncher launcher) {        this.launcher = launcher;    }    /**     * 启动文件选择器以选择图片。     */    public void pickImageFile() {        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);        intent.setType("image/*"); // 选择所有图片类型        intent.addCategory(Intent.CATEGORY_OPENABLE); // 确保文件可被打开        if (launcher != null) {            launcher.launch(intent);        }    }    /**     * 启动文件选择器以选择指定 MIME 类型的文件。     * @param mimeType 文件的 MIME 类型,例如 "application/pdf", "video/*" 等。     */    public void pickSpecificFile(String mimeType) {        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);        intent.setType(mimeType);        intent.addCategory(Intent.CATEGORY_OPENABLE);        if (launcher != null) {            launcher.launch(intent);        }    }}

2. 在 MainActivity 中使用

在 MainActivity 中注册 ActivityResultLauncher,然后将其传递给 FilePickerHelper 的实例。

import android.app.Activity;import android.content.Intent;import android.net.Uri;import android.os.Bundle;import android.widget.Button;import android.widget.Toast;import androidx.activity.result.ActivityResult;import androidx.activity.result.ActivityResultCallback;import androidx.activity.result.ActivityResultLauncher;import androidx.activity.result.contract.ActivityResultContracts;import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity {    private ActivityResultLauncher activityResultLauncher;    private FilePickerHelper filePickerHelper;    private String selectedFilePath; // 用于存储选择的文件路径    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main); // 假设您有布局文件 activity_main.xml        // 1. 注册 ActivityResultLauncher        activityResultLauncher = registerForActivityResult(                new ActivityResultContracts.StartActivityForResult(),                new ActivityResultCallback() {                    @Override                    public void onActivityResult(ActivityResult result) {                        if (result.getResultCode() == Activity.RESULT_OK) {                            if (result.getData() != null) {                                Uri uri = result.getData().getData();                                if (uri != null) {                                    // 实际应用中,处理文件路径可能需要更复杂的逻辑,例如使用 ContentResolver                                    // 这里仅为示例简化处理,可能无法直接获取真实路径                                    selectedFilePath = uri.getPath();                                    Toast.makeText(MainActivity.this, "Selected Path: " + selectedFilePath, Toast.LENGTH_LONG).show();                                }                            }                        } else {                            Toast.makeText(MainActivity.this, "文件选择已取消", Toast.LENGTH_SHORT).show();                        }                    }                });        // 2. 实例化 FilePickerHelper,并注入 activityResultLauncher        filePickerHelper = new FilePickerHelper(activityResultLauncher);        // 3. 在按钮点击事件中调用辅助类的方法        Button pickFileButton = findViewById(R.id.pick_file_button); // 假设布局中有一个ID为 pick_file_button 的按钮        if (pickFileButton != null) {            pickFileButton.setOnClickListener(v -> filePickerHelper.pickImageFile());        }    }}

实现方式二:通过方法参数传递

如果辅助类或方法只需要临时使用 ActivityResultLauncher,或者它是一个静态方法,那么将其作为方法的参数传递会更加简洁。

GarbageSort垃圾识别工具箱 GarbageSort垃圾识别工具

GarbageSort垃圾识别工具箱是一个基于uni-app开发的微信小程序,使用SpringBoot2搭建后端服务,使用Swagger2构建Restful接口文档,实现了文字查询、语音识别、图像识别其垃圾分类的功能。前端:微信小程序 采用 uni-app 开发框架,uni-app 是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、H5、以及各

GarbageSort垃圾识别工具箱 0 查看详情 GarbageSort垃圾识别工具箱

1. 定义辅助类或静态工具方法 (例如 LauncherUtils)

创建一个工具类,包含静态方法,这些方法将 ActivityResultLauncher 作为参数。

import android.content.Intent;import androidx.activity.result.ActivityResultLauncher;/** * 工具类,提供静态方法来启动 ActivityResultLauncher。 */public class LauncherUtils {    /**     * 启动文件选择器。     * @param launcher 已注册的 ActivityResultLauncher 实例。     * @param mimeType 文件的 MIME 类型。     */    public static void launchFilePicker(ActivityResultLauncher launcher, String mimeType) {        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);        intent.setType(mimeType);        intent.addCategory(Intent.CATEGORY_OPENABLE);        if (launcher != null) {            launcher.launch(intent);        }    }    /**     * 启动任意 Activity。     * @param launcher 已注册的 ActivityResultLauncher 实例。     * @param intent 待启动的 Intent。     */    public static void launchActivity(ActivityResultLauncher launcher, Intent intent) {        if (launcher != null) {            launcher.launch(intent);        }    }}

2. 在 MainActivity 中使用

// ... MainActivity 的 onCreate 方法中 ...// 1. 注册 activityResultLauncher (同上文构造函数注入示例)// ...// 2. 在按钮点击事件中调用静态工具方法Button pickPdfButton = findViewById(R.id.pick_pdf_button); // 假设布局中有一个ID为 pick_pdf_button 的按钮if (pickPdfButton != null) {    pickPdfButton.setOnClickListener(v ->        LauncherUtils.launchFilePicker(activityResultLauncher, "application/pdf")    );}// ...

注意事项与最佳实践

生命周期管理: ActivityResultLauncher 是与 Activity 或 Fragment 的生命周期绑定的。确保在 ActivityResultLauncher 活跃的生命周期内调用 launch() 方法。如果 Activity 或 Fragment 已经销毁,调用 launch() 可能会导致崩溃或不期望的行为。

避免内存泄漏: 如果通过构造函数注入的方式将 ActivityResultLauncher 传递给一个生命周期可能长于 Activity 的对象,并且该对象强引用了 ActivityResultLauncher(进而强引用了 Activity),则可能导致内存泄漏。确保辅助类在不再需要时释放对 ActivityResultLauncher 的引用,或者其生命周期与 Activity 保持一致。

接口抽象: 为了进一步解耦和提高可测试性,可以定义一个接口,让辅助类依赖于这个接口而不是具体的 ActivityResultLauncher 实现。这样,在测试时可以轻松地使用模拟对象替换真实实现。

public interface FilePicker {    void pickFile(String mimeType);}// 实现类public class RealFilePicker implements FilePicker {    private final ActivityResultLauncher launcher;    public RealFilePicker(ActivityResultLauncher launcher) { this.launcher = launcher; }    @Override    public void pickFile(String mimeType) {        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);        intent.setType(mimeType);        intent.addCategory(Intent.CATEGORY_OPENABLE);        if (launcher != null) {            launcher.launch(intent);        }    }}// 在 MainActivity 中// FilePicker filePicker = new RealFilePicker(activityResultLauncher);// filePicker.pickFile("image/*");

错误处理: 在 onActivityResult 回调中,始终检查 result.getResultCode() 以判断操作是否成功 (Activity.RESULT_OK),并处理取消 (Activity.RESULT_CANCELED) 或其他失败的情况。

总结

通过将 ActivityResultLauncher 实例作为参数传递,我们能够有效地在 Android 应用的其他类中触发 Activity 结果 API。无论是采用构造函数注入还是方法参数传递,核心思想都是将依赖项显式地提供给需要它的组件。这种做法不仅提高了代码的模块化和可维护性,也使得复杂的交互逻辑能够清晰地分布在不同的职责单元中,是构建健壮 Android 应用的关键实践之一。

以上就是Android ActivityResultLauncher 跨类使用教程的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/897941.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年11月28日 18:44:00
下一篇 2025年11月28日 18:51:02

相关推荐

  • 以太坊是什么币?以太坊ETH获得的方式有哪些?

    以太坊是一个基于智能合约的去中心化应用平台,其原生代币ETH可通过多种方式获取。1、通过Binance必安、欧意ok等中心化平台注册账户、完成KYC认证并用稳定币购买ETH;2、通过去中心化平台连接数字储存,使用稳定币或其他代币直接兑换ETH;3、参与网络质押,可选择独立质押(需32个ETH)、流动…

    2025年12月8日
    000
  • 比特币实时价格查询网站有哪些 可看比特币K线和深度图的网站推荐

    在数字货币市场中,实时掌握比特币价格及其交易深度信息是每个投资者必备的技能。查看精准的k线图和深度图能帮助判断买卖力量,捕捉行情变化,提升投资决策的科学性。 为了更好地跟踪行情,建议新手用户同时注册主流交易平台,如币安Binance和欧易OKX,这样不仅能查看实时价格,还能直接进行买卖操作,提升交易…

    2025年12月8日
    000
  • 稳定币完全手册:6种主流稳定币类型最新介绍

    稳定币作为数字资产领域的重要组成部分,为市场带来了前所未有的流动性和交易便捷性。它们的设计初衷是为了规避加密货币市场剧烈波动的风险,通过锚定法币或其他资产,试图提供一种相对稳定的价值储存和交换媒介。然而,并非所有稳定币都以相同的方式实现其稳定性,市场上的稳定币种类繁多,各具特色,理解它们的工作原理、…

    2025年12月8日
    000
  • 欧意 · 官网注册入口 | 支持中文APP下载与实名认证

    欧意平台提供安全便捷的数字资产服务,用户可通过官方渠道完成下载、注册与认证。1、通过HTX或币安等官网获取应用,进入官方地址下载对应版本;2、根据设备选择苹果或安卓版,忽略系统安全提醒并完成安装;3、使用邮箱或手机号注册,设置强密码并输入验证码完成验证;4、登录后进入个人中心进行实名认证,选择认证等…

    2025年12月8日
    000
  • 稳定币流入助力,以太坊价格创近 6 个月新高

    稳定币流入通过增加需求、提升流动性、作为交易对基础等方式显著推动以太坊价格上涨。1. 需求增加:稳定币流入交易所预示投资者准备兑换为以太坊,直接推高需求;2. 流动性增强:提升市场交易深度,吸引机构参与;3. 规避波动后回流:市场情绪回暖时,稳定币重新投入以太坊等资产;4. 交易对基础:稳定币是主要…

    2025年12月8日
    000
  • 比特币与XRP哪个更值得买?长期回报谁更高?XRP能否成为新霸主?

    对于比特币和XRP哪个更值得投资,以及谁能提供更高的长期回报,市场的看法存在分歧。比特币被许多人视为“数字黄金”,是一种价值储存工具,其稀缺性是其价值主张的核心.另一方面,XRP专注于解决跨境支付问题,旨在取代传统的SWIFT系统,其优势在于交易速度快且成本低. 本文将为您提供一款功能强大的数字资产…

    2025年12月8日
    000
  • 加密货币支持跨链转账吗 不同链之间转账虚拟币需要注意什么

    随着加密生态的快速发展,越来越多的用户开始接触“跨链转账”这一概念。简单来说,跨链转账指的是将某个链上的虚拟币资产转移到另一个链上,例如将eth主网的usdt转到tron链。这类操作在实际使用中非常常见,但也伴随着一些操作风险与技术限制。本文将带你了解跨链转账的基本原理,以及不同链之间转账时的新手注…

    2025年12月8日
    000
  • 以太坊价格走势与市场情绪的紧密关联

    市场情绪深刻影响以太坊价格,1. 信心和贪婪推动价格上涨,2. 恐慌和FUD引发抛售下跌,3. FOMO助长追高行为,4. 群体效应导致羊群行为;典型情绪模式包括牛市乐观与FOMO、熊市悲观与投降式抛售、震荡行情中的观望心态;可通过1. 新闻与社交媒体情绪分析、2. 恐惧与贪婪指数、3. 链上数据分…

    2025年12月8日 好文分享
    000
  • btc交易平台最新版本app下载5.0.5 btc交易平台官方网站APP下载链接

    1、首先确保设备网络稳定并有足够的存储空间;2、通过官方提供的下载地址进行下载;3、根据设备提示完成安装,官方渠道安全可靠;4、安装完成后可体验与HTX、欧易等平台相媲美的专业交易服务;新版本5.0.5功能亮点包括:1、优化用户界面,操作更直观便捷;2、提升交易性能,减少延迟与滑点;3、增强安全防护…

    2025年12月8日
    000
  • 艾达币ADA(艾达币)今日行情价格 艾达币实时K线走势图历史数据汇总

    艾达币(ada)作为第三代区块链平台的原生代币,凭借其领先的技术优势获得了市场的广泛认可。它致力于解决可扩展性、互操作性和可持续性这三大区块链领域的挑战,被誉为“日本以太坊”。艾达币的开发采用了同行评审的科学理念,旨在规避第一代和第二代加密货币的固有缺陷,提供一个更加安全、灵活和可持续的去中心化应用…

    2025年12月8日
    000
  • 欧意app下载交易网 欧意交易所app官方版v6.129.0下载网址

    欧意(Ouyi)APP 是一款专业的数字资产服务平台,致力于为全球用户提供安全、稳定且高效的交易体验。本文将详细介绍其官方版v6.129.0的下载方式与核心功能,帮助用户快速上手。该版本在用户体验、交易性能和安全性方面进行了全面升级,旨在满足不同层次用户的多样化需求,让用户可以便捷地管理和交易其数字…

    2025年12月8日
    000
  • 以太坊注册平台

    在区块链的浩瀚宇宙中,以太坊(ethereum)作为第二大加密货币,其影响力与比特币并驾齐驱。对于初入币圈的新手而言,如何安全、便捷地注册并购买以太坊,无疑是迈向数字资产世界的第一步。本文将深入探讨以太坊的注册平台选择、安全考量以及实际操作流程,助您轻松掌握以太坊的交易精髓。我们将着重分析市场上主流…

    2025年12月8日
    000
  • 欧亿iOS最新版v6.130.0下载 欧亿交易所完整下载流程.手机版下载

    如果你是苹果用户,苦于没有hk地区app store id,可以选择前往官网下载。欧易(okx) 是全球领先的数字资产交易平台,提供现货、合约、理财、web3账户等多项功能。 官网链接: 客户端下载地址(iOS): 1. 前往官网获取OKX官方 iOS 应用 访问上文官方提供的下载地址,点击“APP…

    2025年12月8日 好文分享
    000
  • Yandex币安app最新入口地址 Yandex币安最新版app安装完整指南

    币安(Binance)是全球知名的数字资产交易平台之一,为用户提供广泛的加密货币交易、金融服务以及区块链生态系统支持。其官方App功能强大、操作便捷,是广大数字货币爱好者的常用工具。 本文将为您提供yandex币安最新版app的官方入口地址和一份详尽的安装指南,您只需点击本文中提供的官方下载链接,即…

    2025年12月8日
    000
  • 苹果下载欧意交易所 欧意官网下载app交易所·(苹果版)官方网站

    欧意交易所是一款面向全球用户的专业数字资产服务应用,为用户提供安全、稳定且功能丰富的交易体验。其苹果版官方应用设计简洁,操作流畅,旨在帮助用户便捷地管理和交易各类数字资产,随时掌握市场动态。通过官方网站下载安装,用户可以享受到平台提供的全方位服务。 下载安装步骤 1、为了确保您获取的是官方正版应用,…

    2025年12月8日
    000
  • 以太坊空头达创纪录水平,价格突破在即,投资者如何布局?

    以太坊近期正经历一场前所未有的市场波动,其空头头寸已累积到历史新高,这无疑是市场情绪异常紧张的信号。通常,大规模的空头积累往往预示着一场剧烈的价格反弹,因为当市场逆转时,这些空头头寸将面临巨大的平仓压力,从而进一步推高价格。当前,以太坊的技术图形也显示出突破关键阻力位的迹象,这意味着一次潜在的上涨行…

    2025年12月8日
    000
  • 一文全方位了解GENIUS 稳定币法案解析

    2025年7月18日,美国总统签署了《指导与建立美国稳定币国家创新法案》(简称“GENIUS 法案”),标志着美国在数字资产监管领域迈出了历史性的一步。作为美国首部联邦层面的稳定币专项立法,该法案旨在为“支付型稳定币”建立一套全面、清晰的法律和监管框架。 GENIUS 法案的出台,不仅回应了过去稳定…

    2025年12月8日
    000
  • 以太坊价格走势暗示市场动能转移:比特币沉睡,以太坊活跃

    近期,加密货币市场仿佛进入了一个全新的篇章。曾经的“数字黄金”比特币,似乎正在经历一场深沉的休憩,其价格波动幅度显著收窄,市场关注度也略显平淡。与之形成鲜明对比的是,以太坊(ethereum)正以惊人的活力成为市场的焦点。从技术图表到链上数据,再到围绕以太坊生态的创新活动,无不透露出市场动能正在悄然…

    2025年12月8日
    000
  • USDT虚拟币账户开通攻略 USDT数字资产注册教程

    首先选择信誉良好的数字资产平台,1、推荐币安、欧易、火币、大门交易所等主流平台;2、访问官网点击“注册”,使用邮箱或手机号并设置高强度密码;3、完成邮箱或手机验证码验证;4、登录后进行身份验证(KYC),提交身份证明文件并完成人脸识别;5、启用双重身份验证(2FA)、设置独立资金密码,并定期检查登录…

    2025年12月8日
    000
  • USDT虚拟币购买流程 USDT交易详细完整指南

    首先选择信誉良好的交易平台如币安、欧易、火币或大门交易所;1、注册账户并设置强密码;2、完成身份验证(KYC)提交真实证件;3、通过C2C交易选择合适商家购买USDT并完成支付;4、启用双重身份验证、设置资金密码并定期检查账户活动以确保安全,整个流程需在官方平台操作以防范网络钓鱼,最终顺利完成USD…

    2025年12月8日
    000

发表回复

登录后才能评论
关注微信