Activity Result API 入门:Android 新版 Activity 返回结果机制详解

📅 2026/8/3 3:57:34
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 会轻松很多。