- Published on
Android startActivityForResult()废弃替代方案详解及实例
- Authors

- 作者
- kai
目录

Android startActivityForResult()废弃替代方案详解及实例
在Android开发中,当compileSdk版本为32或更高时,使用传统的startActivityForResult()方法会收到Android Studio的废弃警告。本文将详细介绍官方推荐的替代方案——Activity Result API的使用方法及实例。
为什么需要替代方案
传统的startActivityForResult()方法存在一些设计缺陷:
- 回调处理与启动意图分离,导致代码分散
- 需要重写
onActivityResult()方法,处理所有页面的返回结果 - 类型不安全,需要手动解析返回数据
- 生命周期管理复杂,容易出现内存泄漏
Activity Result API介绍
Activity Result API是Android Jetpack的一部分,提供了更安全、更灵活的Activity结果处理机制,主要包括:
registerForActivityResult():注册Activity结果监听器ActivityResultLauncher:启动Activity的启动器ActivityResultCallback:处理返回结果的回调接口ActivityResultContracts:预定义的启动契约集合
实现步骤
1. 添加依赖
确保在app模块的build.gradle文件中添加必要的依赖:
// 确保app的build.gradle中已经引入了必要的依赖
dependencies {
implementation 'androidx.appcompat:appcompat:1.4.1'
// Activity Result API已包含在appcompat库中
}
2. 源页面(A页面)实现
源页面负责启动目标页面并接收返回结果:
package com.example.test1;
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;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import com.example.test1.ui.login.LoginActivity; // B页面例子
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private static final String TAG = "MainActivity";
// 声明Activity结果启动器
private ActivityResultLauncher<Intent> resultLauncher;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.my_button).setOnClickListener(this);
// 注册Activity结果监听器
resultLauncher = registerForActivityResult(
// 使用预定义的StartActivityForResult契约
new ActivityResultContracts.StartActivityForResult(),
// 实现结果回调处理
new ActivityResultCallback<ActivityResult>() {
@Override
public void onActivityResult(ActivityResult result) {
Log.i(TAG, "接收到Activity结果: " + result);
// 安全检查
if (result != null && result.getResultCode() == Activity.RESULT_OK) {
Intent data = result.getData();
if (data != null) {
// 获取返回的数据
String name = data.getStringExtra("my_name");
String sex = data.getStringExtra("my_sex");
// 处理返回的数据
Log.i(TAG, "获取返回值 my_name: " + name);
Log.i(TAG, "获取返回值 my_sex: " + sex);
// 在这里可以根据返回的数据执行相应的UI更新或业务逻辑
}
}
}
});
}
@Override
public void onClick(View view) {
if (view.getId() == R.id.my_button) {
// 创建跳转到B页面的意图
Intent intent = new Intent(this, LoginActivity.class);
// 可选:向前一个页面传递参数
// intent.putExtra("key", "value");
// 使用启动器启动Activity
resultLauncher.launch(intent);
}
}
}
3. 目标页面(B页面)实现
目标页面负责处理业务逻辑并返回结果给源页面:
// B页面的后退逻辑示例
public void returnToPreviousPage(View view) {
// 1. 创建返回意图
Intent resultIntent = new Intent();
// 2. 封装需要返回的数据
resultIntent.putExtra("my_name", "zhangsan000");
resultIntent.putExtra("my_sex", "男");
// 也可以使用Bundle批量传递数据
// Bundle resultBundle = new Bundle();
// resultBundle.putString("my_name", "zhangsan000");
// resultBundle.putString("my_sex", "男");
// resultIntent.putExtras(resultBundle);
// 3. 设置结果码和数据
// RESULT_OK 表示操作成功
setResult(Activity.RESULT_OK, resultIntent);
// 4. 结束当前页面,返回上一页
finish();
}
代码优化建议
- 使用类型安全的自定义Contract:对于频繁使用的页面跳转,可以定义自定义Contract简化代码:
// 自定义Contract示例
class UserInfoContract extends ActivityResultContract<Void, UserInfo> {
@Override
public Intent createIntent(Context context, Void input) {
return new Intent(context, LoginActivity.class);
}
@Override
public UserInfo parseResult(int resultCode, @Nullable Intent intent) {
if (resultCode != Activity.RESULT_OK || intent == null) {
return null;
}
String name = intent.getStringExtra("my_name");
String sex = intent.getStringExtra("my_sex");
return new UserInfo(name, sex);
}
}
// 使用自定义Contract
resultLauncher = registerForActivityResult(
new UserInfoContract(),
userInfo -> {
if (userInfo != null) {
// 直接使用UserInfo对象
}
}
);
- 在Fragment中使用:在Fragment中使用与Activity类似,但需要注意生命周期:
// Fragment中注册时需要指定生命周期所有者
resultLauncher = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
result -> {
// 处理结果
}
);
总结
Activity Result API相比传统的startActivityForResult()方法,具有以下优势:
- 代码组织更清晰:启动和回调处理封装在一起
- 类型安全:可以通过自定义Contract实现类型安全的数据传递
- 生命周期感知:自动管理生命周期,避免内存泄漏
- 扩展性更好:支持各种预定义的启动契约,也支持自定义契约
通过采用Activity Result API,可以使Android应用的页面间通信更加安全和高效。
