Activity Result API 入门:Android 新版 Activity 返回结果机制详解
文章目录为什么旧方案被弃用Activity Result API 的核心组成注册 LauncherLauncher 到底是什么启动目标 Activity在第二个 Activity 中返回结果回调中的 result 是什么resultCodedata为什么 registerForActivityResult 要放在 onCreate 中数据是如何返回的Activity Result API 的完整流程总结在学习 Android 的 Activity 通信时最先接触到的通常是Intent和putExtra()。启动另一个 Activity 很简单但如果希望打开一个 Activity等待它处理完成再把结果返回给当前 Activity事情就会稍微复杂一些。很多教材仍然使用startActivityForResult()和onActivityResult()但这套方案已经被官方弃用。现在 Android 推荐使用Activity Result API它不仅写法更清晰也更符合 Activity 生命周期的设计。本文从基础开始结合完整代码一步步理解 Activity Result API 的工作方式。为什么旧方案被弃用旧版写法大致如下startActivityForResult(intent,100);然后在当前 Activity 中重写OverrideprotectedvoidonActivityResult(intrequestCode,intresultCode,Intentdata){...}所有返回结果都会集中到这一个方法中再根据requestCode判断是谁返回的。当项目变大之后一个 Activity 可能启动很多不同的页面onActivityResult()会越来越长需要不断写if或switch判断代码可读性和维护性都会变差。Activity Result API 的思路是谁发起请求谁直接注册回调处理结果。这样结果处理逻辑就和启动逻辑放在一起不再需要统一集中处理。Activity Result API 的核心组成整个 API 只有三个核心部分。首先是Launcher。Launcher 可以理解成一个“启动器”专门负责启动某种操作例如启动另一个 Activity、打开相册、请求权限等。其次是ContractActivityResultContract。Contract 用来规定启动时需要传什么参数返回时会得到什么类型的数据。最后是回调函数。当目标 Activity 结束后系统会自动调用回调把结果交给当前 Activity。整个流程可以概括为注册 Launcher↓launch()↓启动目标 Activity↓目标 Activity 返回结果↓自动执行回调注册 Launcher先创建一个简单的页面。MainActivity 中放一个按钮publicclassMainActivityextendsAppCompatActivity{privateActivityResultLauncherIntentlauncher;OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);launcherregisterForActivityResult(newActivityResultContracts.StartActivityForResult(),result-{if(result.getResultCode()RESULT_OK){Intentdataresult.getData();Stringtextdata!null?data.getStringExtra(result):null;Toast.makeText(this,text,Toast.LENGTH_SHORT).show();}});findViewById(R.id.btnOpen).setOnClickListener(v-{IntentintentnewIntent(this,SecondActivity.class);launcher.launch(intent);});}}这里最重要的是registerForActivityResult(...)这个方法完成了 Launcher 的注册。它需要两个参数registerForActivityResult(contract,callback)第一个参数是 Contract。newActivityResultContracts.StartActivityForResult()表示启动一个普通 Activity并等待它返回结果。第二个参数是回调函数。当 SecondActivity 结束时这里的代码会自动执行。Launcher 到底是什么很多初学者看到privateActivityResultLauncherIntentlauncher;容易不理解这个类型。实际上ActivityResultLauncherIntent表示这是一个可以接收 Intent 参数的启动器。因为StartActivityForResult()的输入类型就是Intent。所以后面启动时launcher.launch(intent);相当于把 Intent 交给 LauncherLauncher 再交给系统系统启动目标 ActivityLauncher 本身不负责页面逻辑它只是一个符合生命周期的启动入口。启动目标 Activity启动代码非常简单IntentintentnewIntent(this,SecondActivity.class);launcher.launch(intent);这里已经不需要startActivityForResult();只需要launch(intent);即可。在第二个 Activity 中返回结果创建 SecondActivitypublicclassSecondActivityextendsAppCompatActivity{OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_second);findViewById(R.id.btnFinish).setOnClickListener(v-{IntentintentnewIntent();intent.putExtra(result,来自 SecondActivity 的数据);setResult(RESULT_OK,intent);finish();});}}这里和旧版写法几乎完全一样。返回结果依然使用setResult(resultCode,data);然后调用finish();回调中的 result 是什么注册时, 这里的result类型是ActivityResult, 它主要有两个获取方法result.getResultCode()result.getData()resultCode用于判断目标 Activity 是否成功返回。最常见的是RESULT_OKRESULT_CANCELED因此通常会先判断if(result.getResultCode()RESULT_OK)datadata本质上就是一个Intent。所以可以继续Stringtextresult.getData()!null?result.getData().getStringExtra(result):null;和普通 Intent 取值方式完全一致。为什么 registerForActivityResult 要放在 onCreate 中很多人第一次使用时会疑惑为什么不能点击按钮时再注册button.setOnClickListener(v-{registerForActivityResult(...)});这样是不允许的。Launcher 必须在Activity 生命周期开始阶段完成注册。因为系统需要提前知道谁负责接收结果Activity 重建后如何恢复回调。所以官方要求registerForActivityResult()必须在 Activity 或 Fragment 创建过程中调用。通常写在onCreate()数据是如何返回的很多人会产生一个误解是不是第二个 Activity 直接把变量传回来了其实不是。整个过程依然依赖Intent。SecondActivityIntentintentnewIntent();intent.putExtra(result,Hello);setResult(RESULT_OK,intent);系统会保存这个 Intent。finish(); 执行后MainActivity 回调中result.getData()拿到的就是刚才那个 Intent。putExtra()↓Intent↓setResult()↓系统保存↓ActivityResult.getData()↓getStringExtra()和普通 Intent 传值原理是一致的。Activity Result API 的完整流程把前面的内容串起来整个流程如下。MainActivitypublicclassMainActivityextendsAppCompatActivity{privateActivityResultLauncherIntentlauncher;OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);launcherregisterForActivityResult(newActivityResultContracts.StartActivityForResult(),result-{if(result.getResultCode()RESULT_OK){Stringtextresult.getData()!null?result.getData().getStringExtra(result):null;Toast.makeText(this,text,Toast.LENGTH_SHORT).show();}});findViewById(R.id.btnOpen).setOnClickListener(v-{IntentintentnewIntent(this,SecondActivity.class);launcher.launch(intent);});}}SecondActivitypublicclassSecondActivityextendsAppCompatActivity{OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_second);findViewById(R.id.btnFinish).setOnClickListener(v-{IntentintentnewIntent();intent.putExtra(result,来自 SecondActivity 的数据);setResult(RESULT_OK,intent);finish();});}}运行过程点击按钮↓launcher.launch(intent)↓打开 SecondActivity↓点击返回按钮↓setResult()↓finish()↓MainActivity 回调执行↓Toast 显示数据整个过程中不需要requestCode也不需要onActivityResult()。总结Activity Result API 并没有改变 Activity 返回结果的本质它仍然是Intent setResult() finish()。真正变化的是使用ActivityResultLauncher启动操作使用ActivityResultContract定义输入输出类型使用注册回调代替onActivityResult()。相比旧方案它最大的优势是代码更加模块化与生命周期绑定更加安全。后续学习中你会发现 Android 调用系统相册、拍照、请求权限等功能几乎都建立在 Activity Result API 的基础之上。理解本文的流程之后再学习这些新版 API 会轻松很多。

相关新闻

25 YOLOv8中Bin的偏移量是相对于谁的——网格、乘数与框大小的关系

25 YOLOv8中Bin的偏移量是相对于谁的——网格、乘数与框大小的关系

YOLOv8中Bin的偏移量是相对于谁的——网格、乘数与框大小的关系 前置文档:本文承接 第24篇,假设你已经理解"bin值固定、概率可变、加权求和"的机制。本文聚焦一个24篇没讲透的问题:bin的偏移量是相对于谁的? 一句话总结…

2026/10/9 21:30:25 阅读更多 →
C++哈希表容器unordered_set与unordered_map详解

C++哈希表容器unordered_set与unordered_map详解

1. 无序容器概述:为什么需要hash表?在C标准库中,unordered_set和unordered_map是基于哈希表实现的关联容器。与基于红黑树的有序容器(set/map)相比,它们通过牺牲元素排序性换取了O(1)时间复杂度的查找性能。…

2026/10/14 10:41:00 阅读更多 →
英雄联盟豹女陷阱流玩法解析:符文出装与实战博弈

英雄联盟豹女陷阱流玩法解析:符文出装与实战博弈

在实际《英雄联盟》对局中,豹女(奈德丽)因其高机动性和爆发伤害,一直是高分段和打野玩家热衷的英雄。但“氪金大佬陷阱流”这个说法,通常指代一种高风险、高回报的玩法思路:通过投入大量经济购买特定装备&a…

2026/9/29 12:48:56 阅读更多 →

最新新闻

MADDPG多智能体强化学习Keras实现与协同训练原理

MADDPG多智能体强化学习Keras实现与协同训练原理

简介:本资源是基于Keras框架实现的多智能体强化学习算法MADDPG(Multi-Agent Deep Deterministic Policy Gradient)完整代码工程,面向深度学习与强化学习进阶学习者、多智能体系统研究者及机器人协同控制实践者。项目解决了多智能体…

2026/10/14 15:06:43 阅读更多 →
syzkaller 依赖治理工具 Depguard 深度解析:导入白名单机制、listMode 匹配算法与 golangci-lint 集成

syzkaller 依赖治理工具 Depguard 深度解析:导入白名单机制、listMode 匹配算法与 golangci-lint 集成

测试操作系统网络安全 【免费下载链接】syzkaller syzkaller is an unsupervised coverage-guided kernel fuzzer 项目地址: https://gitcode.com/gh_mirrors/syz/syzkaller 点击查看 免费下载 本文以 syzkaller 仓库 vendor 目录中随 golangci-lint v1.57.2 一同引…

2026/10/14 15:06:43 阅读更多 →
从激活值预测分类器参数:少样本图像识别的生成式解法

从激活值预测分类器参数:少样本图像识别的生成式解法

被一组只有五张图的新类别困住的时候,大多数模型的反应是迷茫。少样本图像识别(few-shot image recognition)要解决的,就是在这样苛刻的条件下,让模型尽量快地进入状态。我今天想聊的这篇论文,标题起得很直…

2026/10/14 15:06:43 阅读更多 →
多相信道化接收机原理与MATLAB实现:宽带ADC高效信道化设计

多相信道化接收机原理与MATLAB实现:宽带ADC高效信道化设计

简介:多相结构信道化接收机是宽带信号高效分解为窄带信道的关键技术,在无线电监测、软件定义通信与信号侦察等领域应用广泛。面向通信工程专业学生、从事信号处理研究的开发者及需要完成相关毕业设计的读者,本资源以单文件MATLAB程序fengkui_…

2026/10/14 15:06:43 阅读更多 →
基于MSP432与OpenMV的自动泊车系统:从硬件连到泊车入位

基于MSP432与OpenMV的自动泊车系统:从硬件连到泊车入位

简介:面向嵌入式与机器视觉学习者的一套自动泊车系统完整工程包,基于MSP432P401R微控制器与OPENMV摄像头,覆盖车位识别、传感器解析、车辆控制及上位机交互等环节,适合课程设计、竞赛备赛或项目入门。压缩包共245个文件&#xff0…

2026/10/14 15:06:43 阅读更多 →
基于SpringBoot+Vue的铁路订票系统设计与实现

基于SpringBoot+Vue的铁路订票系统设计与实现

1. 项目概述与核心价值铁路订票管理系统是一个典型的B/S架构企业级应用,采用前后端分离模式开发。前端基于Vue.js框架实现响应式用户界面,后端采用SpringBoot提供RESTful API服务,数据存储使用MySQL关系型数据库。这个项目特别适合作为计算机…

2026/10/14 15:05:42 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →