为什么必须在onDestroyView()中调用clearFindViewByIdCache()?

时间:2019-04-09 22:28:05

标签: android xml kotlin kotlin-android-extensions

我试图了解Kotlin Android扩展,this article说:

When asked for a view, it will try to find it in the cache. If it’s not there, it will find it and add it to the cache. Pretty simple indeed.

Besides, it adds a function to clear the cache: clearFindViewByIdCache. You can use it for instance if you have to rebuild the view, as the old views won't be valid anymore.

在onDestroy()之后重建视图后,为什么旧​​视图不再有效?重建视图后,视图引用仍将存在,例如在OnActivityCreated()中。

1 个答案:

答案 0 :(得分:0)

这里重要的一点是,片段通常比其视图具有更长的生命周期。让我们考虑以下流程:

  1. 您创建了Fragment A并将其放入容器中
  2. Fragment A视图已创建(此onCreateView + onViewCreated)
  3. 您创建了Fragment B,并用容器中的新片段替换了Fragment A,并保留了后退堆栈
  4. Fragment A此时将被销毁,但片段将保留在FragmentManager内部。
  5. back press和片段B被完全销毁了,因为您从逻辑上离开了它。此时,系统将其替换为Fragment A,并再次创建一个新视图。

以下是一些重要说明:

在第4步中,如果您保留到子视图的任何链接,则您的内存只会泄漏,因为所有它们都已从视图层次结构中分离出来,无法再使用。基本上,您仍然将所有这些视图保留在内存中,即使它们不再被使用。通常,ppl不会注意到,所有视图都会通过新的onViewCreated(和findViewById)再次反弹,但是kotlin扩展将其保留在缓存中,并且基本上不会再次执行此findViewById,因此您可能会变成旧的(读作废)视图,而不是刚刚创建的视图。

例如,如果您现在使用ButterKnife,他们在Binding Reset部分中也对此进行了描述。 (http://jakewharton.github.io/butterknife/#reset)。

最后一点要注意的是Kotlin扩展会为您完成这项工作,因此您实际上不需要在onDestroyView内调用它,只需使用它就可以了(就像魔术一样……)