1

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

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

该应用程序第一次运行时,它运行良好。

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

然而这一次,当我的演示者发布线程获取数据线程并完成并将结果发送到 UI 时,片段的 isAdded() 方法返回 false 并且 getActivity 为空。

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

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

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

4

2 回答 2

0

碎片和活动都应该被销毁。您永远不能依赖 android 框架组件的生命周期状态,并且因此制作了 android 架构组件。例如,ViewModel 的寿命可能比它的宿主片段长。

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

有应用程序架构的官方指南。简而言之,您有一个用于更新 UI 的 android 相关代码层、用于处理应用程序逻辑的层(独立于 java/kotlin 和 android 框架)和用于请求/保存数据的层。因此,在创建 ui 类期间,您会获得 viewmodel,它引用了处理逻辑的类并将结果公开以在 ui 中呈现。内层是持久的 - 视图不是。

于 2020-02-23T00:43:50.323 回答
0

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

我在 Fragment 的 onDestroy/onDetach 方法中取消了演示者的观点。然而,当替换 Fragment 被创建时,这个新的 Fragment 首先被附加到调用的 Activity 上,然后旧的 Fragment 被销毁。

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

结果,当结果通过回调到达 UI 线程时,此视图对象“未添加”。

于 2020-02-24T09:46:33.443 回答