Android Fragment被销毁却接收到onActivityResult

6
感谢这个回答 Android Fragment生命周期问题(onActivityResult中的NullPointerException),我成功地重新创建了一个场景,当我调用startActivityForResult后,在我的Fragment中收到了一个NPE。 所以我有:
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("image/*");
startActivityForResult(photoPickerIntent, PHOTO_SELECT_REQUEST_CODE);
break;

被从我的片段调用,然后我的活动接收到onPause、onStop和onDestroy,因此调用了startActivityForResult的片段也会收到一个onDestroy。在我选择一张图片之后,我会得到一个新的activity onCreate,然后我会在原来被销毁的片段上得到一个public void onActivityResult。
我的问题是,由于这可能是一个(虽然罕见的)情况,如何恢复整个片段栈和传递给它们的对象,并防止原始片段泄漏?

你确定onActivityResult被传递到旧的fragment了吗?你尝试在onCreate/onCreateView和onActivityResult中记录fragment对象(this)了吗?这将让你清楚地知道哪个fragment调用了onActivityResult。 - Rahul Shukla
1个回答

1
当你的代码执行以下行:

时:

startActivityForResult(photoPickerIntent, PHOTO_SELECT_REQUEST_CODE);

每次您的活动将会得到onPause()onStop(),但不是onDestroy()。如果Android系统在运行时内存不足,则可能会onDestroy()您的活动。
为了保存片段和活动的状态并防止泄漏:
onSaveInstanceState(Bundle)中保存您的状态。
在系统需要更多内存的情况下,它可能会终止暂停的进程(在onPause()之后)以回收资源。因此,您应该确保从此函数返回时已保存所有状态。通常onSaveInstanceState(Bundle)用于在活动中保存每个实例的状态,而此方法用于存储全局持久数据(在内容提供程序、文件等中)。
onRestoreInstanceState(Bundle)中恢复您的状态。

onRestoreInstanceState(Bundle) 方法在活动从先前保存的状态重新初始化时,在 savedInstanceState 中给出后,会在 onStart() 后被调用。大多数实现将简单地使用 onCreate(Bundle) 来恢复它们的状态,但有时在所有初始化完成后或允许子类决定是否使用默认实现后,在此处执行可能更方便。此方法的默认实现将还原之前由 onSaveInstanceState(Bundle) 冻结的任何视图状态。

这可能有助于您实现您的需求。


谢谢您的回答。我已经根据 onSaveInstanceState / onRestoreInstanceState 监听器实现了重新创建活动和片段的逻辑。然而,我仍然面临“剩余”片段问题。由于它已注册接收活动结果,因此不会被标记为 GC,并且我无法想到一种好的方法将该结果转发到重新创建的片段中。 - Dmitry Golomidov
@DmitryGolomidov,你找到答案了吗?我也遇到了同样的问题。 - kong
@kong 我这里也有同样的问题。有什么新消息吗? - Juan Ignacio Barisich
我遇到了同样的问题,而且我正在使用导航组件。有什么解决方案吗? - Vish

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