方向改变后,Fragment的onActivityResult方法没有被调用

11
请注意,这个问题与以下问题不重复: 此外,之前也有一个类似的问题,但没有提到方向更改(而且未解决)。
我的Fragment中的onActivityResult方法在不切换方向时会被调用。然而,如果我按照以下步骤操作,它就不会被调用:
  1. 在FragmentActivity中加载片段。
  2. 从片段: startActivityForResult(new Intent(MediaStore.ACTION_IMAGE_CAPTURE), Constants.REQ_CODE_IMAGE_CAPTURE);
  3. 等待相机加载。
  4. 切换方向。
  5. 拍照并点击勾号。

onActivityResult仍会在父FragmentActivity中被调用。但是,由于我收到了这个警告:

W/FragmentActivity(4418): Activity result no fragment exists for index: 0x22d73

我的猜测是,由于方向改变,父级被销毁了,然后在重新创建之后,无法找到最初调用startActivityForResultFragment。这是框架的一个bug吗?如何解决这个问题? 编辑:根据大家的要求,添加了更多代码。

FragmentActivity.java:

...

fragment = new ExampleFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace (R.id.mainContentView, fragment);
if (clearBackStack) {
    // clear the back stack
    while (getSupportFragmentManager().popBackStackImmediate ());
    // add the current transaction to the back stack
    transaction.addToBackStack (null);
}
else {
    transaction.addToBackStack(null);
}
transaction.commit();

...

@Override
public void onActivityResult(int reqCode, int resultCode, Intent data) {
    super.onActivityResult(reqCode, resultCode, data);
}

ExampleFragment.java:

Intent takePicture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(takePicture, Constants.REQ_CODE_IMAGE_CAPTURE);

...

@Override
public void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
    super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
    switch (requestCode) {
    case Constants.REQ_CODE_IMAGE_CAPTURE:
        // handle added image
    }
}

支持库存在问题。请查看此文章:http://shomeser.blogspot.com/2014/01/nested-fragments-for-result.html - Oleksii K.
@shomeser,我在搜索时看到了你的帖子,但是我没有嵌套片段,所以我认为这与我的问题无关。 - Shade
你的代码片段索引太大了:0x22d73,看起来发生了一些奇怪的事情。这个问题是否稳定重现?你能展示一下你的代码吗? - Oleksii K.
@shomeser,我的代码没有什么特别的地方,但请看编辑。如果您按照提供的步骤操作,问题总是可以重现。 - Shade
你尝试过在beginTransaction()之前移动popBackStackImmediate()的调用吗? - Oleksii K.
2个回答

2
通过将所有的onActivityResult逻辑从Fragment移到Activity来解决了这个问题。
请注意,传递给FragmentreqCode与传递给父ActivityreqCode不同(我认为是系统设置活动的)。这意味着我还必须将原始的startActivityForResult调用从Fragment移到Activity,然后在需要时从Fragment创建一个方法来调用它。
如果有人发现更优雅的方法,请告诉我。

1
请查看方法FragmentActivity.startActivityFromFragment(),它修改了原始请求代码以存储Fragment的索引:http://goo.gl/yuaPWW 这就是为什么你得到不同的值。很遗憾,目前我无法重现这个问题。 - Oleksii K.
那个修复方法对我有用。这个问题只在一些设备上出现(Galaxy S5 没问题,但是在 Sony XPeria 上出错了)。 - Arnaud
在我的情况下,onActivityResult 已经在我的 Activity 类中了。但我仍然注意到相同的行为。 - Neon Warge

1
我可以帮忙翻译。这是一段关于编程的内容。

我有一个解决方案,目前在我的项目中运行良好。按照以下步骤:

--> 创建接口名称为OnActivityResultListener(或您想要的名称)。

public interface OnActivityResultListener {

public boolean onActivityResultTest(int request_code, int response_code,
        Intent data);

}

--> 在您的 FragmentActivity 中引用接口,如下所示:

public OnActivityResultListener activityResultListener;

-->现在重写FragmentActivity中的OnActivityResult方法,如下所示。

@Override
public void onActivityResult(int arg0, int arg1, Intent arg2) {
    AppLog.Log(TAG, "onActivityResult");
    try {
        if (activityResultListener != null) {
            activityResultListener.onActivityResultTest(arg0,arg1,arg2);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    super.onActivityResult(arg0, arg1, arg2);
    }

--> 现在在您的Fragment中实现接口并覆盖所需的方法。

@Override
public boolean onActivityResultTest(int requestCode, int resultCode,
        Intent data) {
    AppLog.Log(TAG, "onActivityResultTest");
    if (requestCode == CAMERA_REQUEST && resultCode == Activity.RESULT_OK) {
        isHavePhoto = true;
        bitmap = (Bitmap) data.getExtras().get("data");
        userEditPhoto.setImageBitmap(bitmap);
    }
}

--> 最后一步是在Fragment类的OnAttach方法中注册您的Fragment以获取Activity结果,例如:

@Override
    public void onAttach(Activity activity) {
        this.activity = (YOUR_FRAGMENT_ACTIVITY) activity;
            this.activity.activityResultListener = this;
        super.onAttach(activity);
    }

-->现在测试,不要忘记将其移除

@Override
public void onDestroyView() {
    activity.activityResultListener = null;
    super.onDestroyView();
}

->这是一个有些冗长的过程,但在任何方向上都可以完美运行。


不支持Android 4.4,Nexus 5,支持库的19.0.1版本。片段在Activity的onActivityResult被调用后附加,因此在调用时侦听器为空。 - Shade
抱歉,但它在4.4上运行正常,我已经在Nexus 4和5上测试过了,它可以正常工作。你需要告诉我,我认为你可能在onAttach方法上有问题,请再检查一遍所有步骤。 - Imtiyaz Khalani
那可能是这样。然而,在我目前的情况下,这对我没用。 - Shade
运行良好,只需从活动中调用startActivityForResult(activity?.startActivityForResult)即可。 - Francis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接