Android setResult 无法传递到上上一层
在Android开发中,我们经常会使用startActivityForResult
方法来启动一个新的Activity,并期望在新的Activity中返回结果给上一层的Activity。然而,有时候我们可能会遇到一个问题,就是无法将结果传递回到上上一层的Activity。本文将详细解释这个问题,并提供解决方案。
问题描述
首先,让我们来看一个典型的场景。假设我们有一个应用程序,包含两个Activity:Activity A和Activity B。在Activity A中,我们通过startActivityForResult
方法启动Activity B,并期望在Activity B中返回结果给Activity A。然而,在Activity B中,我们又通过startActivityForResult
方法启动了一个新的Activity,即Activity C。此时,我们期望在Activity C中返回结果给Activity A,而不是Activity B。然而,无论我们如何尝试,都无法将结果传递回到Activity A。
这个问题的根本原因是,startActivityForResult
方法只能将结果传递给直接调用它的Activity,而无法传递给间接调用它的Activity。换句话说,它只能传递到上一层的Activity,而无法传递到上上一层的Activity。
问题分析
为了更好地理解这个问题,让我们来看一下startActivityForResult
的工作原理。当我们调用startActivityForResult
方法启动一个新的Activity时,Android系统会创建一个新的任务栈,并将新的Activity添加到该任务栈中。如果我们在新的Activity中再次调用startActivityForResult
方法启动另一个Activity,系统会再次创建一个新的任务栈,并将新的Activity添加到该任务栈中。
下图是一个示意图,展示了上面描述的场景。每个方框代表一个Activity,箭头表示startActivityForResult
方法的调用。
erDiagram
ActivityA --> ActivityB : startActivityForResult
ActivityB --> ActivityC : startActivityForResult
从图中可以看出,Activity A启动了Activity B,Activity B又启动了Activity C。如果我们在Activity C中设置结果并调用finish
方法,结果将会传递回到Activity B。这是因为Activity C直接调用了startActivityForResult
方法的Activity是Activity B。
但是,如果我们希望结果传递回到Activity A,即上上一层的Activity,就会遇到问题。这是因为Activity C无法直接将结果传递给Activity A,而只能传递给Activity B。即使我们在Activity C中调用setResult
方法设置结果,并在Activity B中再次调用setResult
方法设置结果,结果仍然无法传递到Activity A。
解决方案
为了解决这个问题,我们需要借助一个中间层来传递结果。具体来说,我们可以在Activity B中创建一个新的方法,用于接收Activity C的结果,并将结果传递给Activity A。
以下是代码示例:
// Activity A
public class ActivityA extends AppCompatActivity {
private static final int REQUEST_CODE = 1;
// 启动 Activity B
private void startActivityB() {
Intent intent = new Intent(this, ActivityB.class);
startActivityForResult(intent, REQUEST_CODE);
}
// 处理 Activity B 返回的结果
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE && resultCode == RESULT_OK) {
// 处理结果
}
}
}
// Activity B
public class ActivityB extends AppCompatActivity {
private static final int REQUEST_CODE = 2;
// 启动 Activity C
private void startActivityC() {
Intent intent = new Intent(this, ActivityC.class);
startActivityForResult(intent, REQUEST_CODE);
}
// 处理 Activity C 返回的结果
private void handleActivityResult(int resultCode, Intent data) {
setResult(resultCode, data);
finish();
}
// 处理 Activity C 返回的结果
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE && resultCode == RESULT_OK) {
handleActivityResult(resultCode, data);
}
}
}
// Activity C
public class ActivityC extends AppCompatActivity