startActivityForResult 是 Android 开发中用于启动新活动并获取返回结果的一个方法。它用于启动一个活动,并且等待这个活动完成后返回结果。这个方法通常用于处理一些需要从另一个界面获取数据的场景,比如选择图片、编辑信息、登录等。

1. 基本用法

使用 startActivityForResult 时,我们需要指定一个请求代码(request code),这个代码用于标识当前请求,返回的结果会通过这个请求代码来区分。返回结果会在 onActivityResult 方法中处理。

基本步骤

  1. 使用 startActivityForResult 启动目标活动。
  2. 在目标活动完成后返回数据。
  3. 在调用活动的 onActivityResult 方法中获取结果。

2. 示例代码

1) 启动活动并获取结果

// 在当前 Activity 中调用 startActivityForResult 来启动目标 Activity
Intent intent = new Intent(CurrentActivity.this, TargetActivity.class);
startActivityForResult(intent, 100);  // 100 是请求码

2) 在目标 Activity 中返回结果

// 在目标 Activity 中返回结果
Intent resultIntent = new Intent();
resultIntent.putExtra("resultKey", "some data"); // 添加需要返回的数据
setResult(Activity.RESULT_OK, resultIntent);  // RESULT_OK 是常量,表示成功
finish(); // 结束当前 Activity 并返回

3) 处理返回结果

// 在启动 Activity 的 Activity 中重写 onActivityResult 方法来接收返回的数据
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    
    // 判断请求码是否匹配
    if (requestCode == 100) {
        if (resultCode == RESULT_OK) {
            // 获取返回的数据
            String result = data.getStringExtra("resultKey");
            Log.d("Result", "Received result: " + result);
        } else {
            Log.d("Result", "Operation cancelled or failed");
        }
    }
}

3. 详细说明

3.1 startActivityForResult 的参数

  • Intent:用于启动目标 Activity 的 Intent 对象,包含了启动目标 Activity 所需的所有信息。
  • requestCode:请求码,用来区分不同的请求。在目标 Activity 返回结果时,requestCode 将用于确定是哪个请求的结果。

3.2 onActivityResult 的参数

  • requestCode:请求码,用来标识哪个请求。
  • resultCode:返回结果的状态,通常是 RESULT_OK 或 RESULT_CANCELED
  • data:返回的 Intent 数据,包含返回的结果。如果没有返回数据,则 data 可能为 null

3.3 RESULT_OK 和 RESULT_CANCELED

  • RESULT_OK:表示操作成功。
  • RESULT_CANCELED:表示操作取消或失败。

4. 示例:选择图片

以下是一个典型的使用 startActivityForResult 的例子,展示了如何选择图片并返回选中的图片路径。

1) 启动选择图片的活动

Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, 200);  // 200 是请求码,用于标识选择图片的请求

2) 处理返回的结果

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    
    if (requestCode == 200) {
        if (resultCode == RESULT_OK) {
            Uri selectedImage = data.getData();  // 获取选中的图片的 URI
            // 处理选中的图片 URI,例如显示图片
            imageView.setImageURI(selectedImage);
        } else {
            // 用户取消了选择
            Toast.makeText(this, "Image selection cancelled", Toast.LENGTH_SHORT).show();
        }
    }
}

5. startActivityForResult 的替代方法:ActivityResult API

在 Android 11(API 级别 23)及之后,Google 引入了 ActivityResult API,这是一种新的方式来处理活动之间的结果传递,目的是简化 startActivityForResult 的使用并解决一些问题(如权限请求等)。

1) 使用 ActivityResultContract 和 ActivityResultLauncher

// 创建一个 ActivityResultLauncher 用于启动目标 Activity
ActivityResultLauncher<Intent> resultLauncher = registerForActivityResult(
    new ActivityResultContracts.StartActivityForResult(),
    new ActivityResultCallback<ActivityResult>() {
        @Override
        public void onActivityResult(ActivityResult result) {
            if (result.getResultCode() == RESULT_OK) {
                Intent data = result.getData();
                // 处理返回的结果
                String resultData = data.getStringExtra("resultKey");
                Log.d("Result", "Received: " + resultData);
            }
        }
    });

// 启动目标 Activity
Intent intent = new Intent(CurrentActivity.this, TargetActivity.class);
resultLauncher.launch(intent);

2) 优势:

  • 更简洁ActivityResultLauncher 代替了 startActivityForResult,减少了繁琐的代码。
  • 更安全:可以避免在不同的 Activity 中手动管理请求码,减少了错误的可能性。
  • 支持权限请求ActivityResultContracts.RequestPermission() 和 ActivityResultContracts.RequestMultiplePermissions() 提供了更加方便的权限请求处理。

6. 总结

  • startActivityForResult 是一个非常有用的方法,适用于启动活动并获取返回数据的场景。
  • 在 Android 11 及之后的版本,推荐使用 ActivityResult API 来替代 startActivityForResult,它提供了更简洁、强大的功能,尤其在权限请求和结果处理上更为便捷。
  • 在实际应用中,根据 Android 版本选择合适的 API,以确保应用的稳定性和可维护性。