【问题标题】:Android Fragment isAdded returns false and getActivity is null after posting thread in the onResume methodAndroid Fragment isAdded 在 onResume 方法中发布线程后返回 false 并且 getActivity 为 null
【发布时间】:2020-06-06 23:32:27
【问题描述】:

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

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

应用程序第一次运行时,一切正常。

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

然而这一次,当我的演示者发布线程 fetching-data-thread 并完成并将结果发送到 UI 时,fragment 的 isAdded() 方法返回 false 并且 getActivity 为 null。

拥有它,意味着我不能使用活动上下文(getActivity() 为 null 或 requireActivity() 引发非法状态异常),因此我无法加载图像等,因为我没有可用的上下文。

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

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

【问题讨论】:

    标签: android android-fragments android-lifecycle fragmentmanager android-components


    【解决方案1】:

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

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

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

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

    【讨论】:

      【解决方案2】:

      Fragment 和 Activity 都应该被销毁。 你永远不能依赖 android 框架组件的生命周期状态,因此 android 架构组件是made。例如,ViewModel 的寿命可能比它的宿主片段长。

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

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

      【讨论】:

      • 首先,非常感谢您的回复。其次,我知道 Android 生命周期,让我告诉你,我的演示者唯一要做的就是调用我的存储库来获取数据,然后在此任务完成后,它负责将结果传递给 UI。此外,我使用here 描述的“手动依赖注入”之类的模式在片段之外创建我的演示者。
      • 所以,如果数据保存在存储库中,那么ui被破坏真的不是问题。重新创建片段获取时,它的演示者可以访问保存的数据,并且可以将其传递给片段。
      • 是的。问题是我的演示者没有被告知新的“视图”对象,也就是新的片段实例。
      猜你喜欢
      • 2014-04-24
      • 1970-01-01
      • 1970-01-01
      • 2011-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-21
      • 2013-09-05
      相关资源
      最近更新 更多