Navigation Arch Component会造成假阳性内存泄漏吗?

时间:2019-12-27 16:48:10

标签: android kotlin memory-leaks android-architecture-navigation leakcanary

我对内存泄漏以及可能导致它们的原因有基本的了解。这就是为什么我不明白自己的代码有问题还是误报的原因。我不知道我应该共享代码的哪一部分,因为该项目并不小。但是请在评论中让我知道,然后我将添加所需的代码。

我使用导航拱形组件并遵循MVVM模式。我后来在项目开发中添加了LeakCanary库,当我在屏幕之间导航时,它立即开始向我发出有关保留实例的警告。

当我向后堆栈中添加片段时,会出现问题。随着向后堆栈中添加的每个片段,保留实例的计数器增加。当阈值达到5时,LeakCanary将转储堆并提供报告。

但是,如果我单击“后退”按钮并返回到先前的屏幕,则保留实例的计数器会减少,最终,当返回到第一个屏幕时,所有保留的实例都会消失。

如果我查看堆分析报告,它表示变量coordinatorLayout泄漏了xml中对CoordinatorLayout的引用。如果删除该变量及其所有用法,然后再次运行该应用程序,我会看到相同的问题,但是现在有了另一个变量,该变量引用了xml中的另一个视图。我试图删除LeakCanary报告为泄漏的所有视图及其用法。当它说TextView只是用于在onViewCreated中设置文本而未在其他任何地方使用时,正在泄漏我开始怀疑我的代码有问题。

我分析了片段中的生命周期方法调用,并注意到当我导航到先前片段的新屏幕时,直到(包括)onDestroyView之前的所有方法都被调用,而没有onDestroy。当我单击后退时,onDestroy被调用以返回位于后退堆栈顶部且保留实例计数器减少的片段。

我怀疑导航组件在回栈中并且LeakCanary将其视为泄漏时正在保留片段的实例。

1 个答案:

答案 0 :(得分:2)

这就是后堆栈上的片段的工作方式(导航仅使用现有的Fragment API):片段的视图被破坏了,但是片段本身并未被破坏-它们一直处于if(showLoading) { this.displayLoader(); return; } else { render (); //your main view 状态,直到您点击返回按钮并返回片段(此后将再次调用CREATED,然后您将返回到onCreateView())。

根据Fragments: Past, Present, and Future talk,对Fragments的未来更改之一是选择启用选项以销毁后堆栈上的Fragment,而不是具有两个单独的生命周期。目前尚不可用。

您必须在RESUMED中取消对视图的引用,因为这表明Fragment系统不再使用该视图,并且如果您不打算继续使用该视图,则可以安全地对其进行垃圾回收对视图的引用。