Android Fragment isAdded returns false 并且在 onResume 方法中发布线程后 getActivity 为 null

Android Fragment isAdded returns false and getActivity is null after posting thread in the onResume method

所以我在我的应用程序的主要 activity 中使用导航,我有一个片段是我的开始导航片段。

在这个片段中,创建后,在我的演示者中我 post 一个从网络获取数据的线程。 获取数据后,我正在使用主线程将数据显示到我的屏幕上。

应用第一次运行时,运行良好。

但是,如果用户打开抽屉并再次选择此片段而不是另一个片段,则会再次重新创建片段,这意味着它会像导航组件设计的那样被销毁并从头开始创建。

但是这次,当我的演示者 post 的线程获取数据线程完成并将结果发送到 UI 时,片段的 isAdded() 方法 returns false 以及 getActivity 为 null.

有那个,意味着我不能使用 Activity 上下文(getActivity() 为 null 或 requireActivity() 抛出非法状态异常)因此我无法加载图像等,因为我没有可用的上下文。

我强调,当用户在该片段可见时打开抽屉并再次选择从抽屉导航到该片段时,会发生这种情况。如果用户导航到另一个片段,然后按下后退按钮,一切正常。

知道如何处理这个问题吗?

碎片是要被销毁的,活动也是如此。 您永远不能依赖 android 框架组件生命周期状态,因此 android 架构组件是 made。例如,ViewModel 的寿命可能超过它的主机片段。

但是 - viewmodel/presenter/controller 不是执行网络请求和处理应用程序逻辑的正确位置,因为这不是他们的工作(SOLID 的 S- 单一责任)。

应用架构有官方 guide。简单地说,你有一个用于 android 相关代码的层,你可以在其中更新 UI,用于处理应用程序逻辑的层(与 java/kotlin 和 android 框架无关)和层对于 requesting/holding 数据。 因此,在创建 ui class 期间,您获得了视图模型,它引用了 class 来处理逻辑并公开结果以在 ui 中呈现。保留内层 - 视图不是。

所以,经过测试和搜索,我发现了上述问题的根源。

我在片段的 onDestroy/onDetach 方法中使演示者的视图无效。 但是,当创建替换片段时,这个新片段首先附加到调用 Activity,然后旧片段被销毁。

请记住,我将我的 Presenter 注入到 Fragment 实例中,我的 Presenter 在附加新 Fragment 时永远不会为空,因此,考虑到我创建了一个新的 Presenter 实例,当它是null,被注入到片段中的演示者实例不知道新的 'View' 对象。

因此,当结果通过回调到达UI线程时,这个视图对象是'not Added'。