非法状态异常 - Fragment.getResources

3
在我的碎片中,我在许多地方使用资源字符串。理想情况下,一切都正常工作。
但是,我经常收到崩溃报告,报告显示 IllegalStateException,表示片段未附加到活动中。我能想到的一个可能的解决方案是使用 isAdded() 方法来返回是否将片段附加到活动中,但在访问字符串资源之前在所有地方使用它似乎不是一个正确的解决方案,因为它可能会破坏流程。
此外,我可以使用以下实现,但不确定是否正确?在片段的 onAttach 中初始化 mActivity,然后使用它来获取资源字符串。
@Override
public void onAttach(Context context) {
    super.onAttach(context);
    if (context instanceof Activity) {
        mActivity = (Activity) context;
    }
}

与其

 getString(R.string.string_resource)

使用

mActivity.getString(R.string.string_resource)

我能否确信使用这个方法会停止 IllegalStateExceptions 的出现?


你能发布一下ActivityFragment的代码吗?或者是出现错误的函数? - Susmit Agrawal
@SusmitAgrawal 整个活动和片段的代码会很繁琐,我在Retrofit请求的onResponse方法中遇到了这个异常。 - Mihir Patel
@MihirPatel 请提供 IllegalStateException 的堆栈跟踪以及此跟踪中列出的方法。听起来问题是您在生命周期的早期阶段(在调用 onAttach 之前)执行了某些操作。 - Janus Varmarken
你能贴上堆栈跟踪吗? - CodeSmith
1个回答

6

我能确信使用这个方法可以阻止IllegalStateExceptions的出现吗?

不,绝对不能。Fragment.getString() 内部委托给 requireContext().getResources(),而 requireContext() 只有在 Fragment 依附于 Activity 时才会返回一个值。因此,你仍然会遇到相同的问题,只是代码更多了。

你的问题在于在生命周期的无效阶段调用了 getString() 方法。你提到这是在 Retrofit 响应中发生的,所以我的假设是你在 Fragment 中提交了一个网络请求,并提供了一个匿名的响应监听器(它持有对你的 Fragment 的引用)。该请求将在 Fragment 被分离后继续进行,然后在响应监听器中调用 getString()

考虑使用Android 架构组件(特别是ViewModelLiveData),并让您的ViewModel执行请求,并将结果发布到LiveData(您的Fragment可以观察)。这样,您将保证仅在有效的生命周期状态下处理结果,并且请求还将在配置更改期间保持。

谢谢@kcoppock。您能否分享一些关于您所提到的架构组件的参考资料?这将非常有帮助。 - Mihir Patel
当然,我已经在Arch组件、ViewModel和LiveData的介绍文档中添加了一些内联链接。 - Kevin Coppock
我在生产环境中的Fragment onActivityCreated()方法中遇到了崩溃,这些方法除了调用getString()(没有后台请求)之外什么也不做。我无法重现并且不知道如何预防 - 将可能使用getResources()的所有内容移动到onResume()中是否可行? - Daniel Wilson

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