android - 为什么必须在 onDestroyView() 中调用 clearFindViewByIdCache()?
问题描述
我试图了解 Kotlin Android 扩展,这篇文章说:
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() 中。
解决方案
这里重要的一点是,片段的生命周期通常比它们的视图更长。让我们考虑以下流程:
- 您创建
Fragment A
并将其放入容器中 Fragment A
视图已创建(此 onCreateView + onViewCreated)- 您在容器中创建
Fragment B
并替换Fragment A
为新片段 + 保留堆栈 Fragment A
此时视图将被销毁,但片段将保留在FragmentManager
.- 你
back press
和 Fragment B 被完全摧毁了,因为你合乎逻辑地离开了它。此时系统将其替换回来Fragment A
并再次创建一个新视图。
所以这里有一些重要的注意事项:
在步骤#4,如果您保留任何指向子视图的链接,那么您的内存就会泄漏,因为所有这些都已经从您的视图层次结构中分离出来并且不能再使用了。基本上,您仍然将所有这些视图保存在内存中,即使它们不再使用。通常,人们不会注意到这一点,并且所有视图都会使用新的 onViewCreated(和findViewById
)再次反弹,但是 kotlin 扩展将它们保存在缓存中并且基本上不会findViewById
再次执行此操作,因此您可以获得旧的(读作死的)视图不是刚刚创建的那些视图。
例如,如果你现在使用 ButterKnife,他们也会在Binding Reset
部分中对此进行描述。(http://jakewharton.github.io/butterknife/#reset)。
最后重要的一点是 Kotlin 扩展为您完成了这项工作,因此您实际上不需要在 onDestroyView 内部调用它,您只需使用它就可以了(就像魔术一样......)
推荐阅读
- swift - Alamofire 合并多个文件的上传进度
- ant-design-pro - 翻译 Ant Design Pro Table 默认表的默认操作
- amazon-web-services - 无法将 google Dns 确认 Txt 记录添加到 Godaddy 的名称服务器
- .net - 在 API 和后端之间使用什么作为队列
- c# - 我可以在这个查询中使用 lastordefault 或 firstordefault 吗?怎么能?
- asp.net-mvc - 在 asp.net MVC 应用程序中展开行时,Kendo 嵌套网格绑定内部网格
- node.js - 避免统一请求标头中的 Content-Length
- c# - 如何过滤子集合,将 datetime 属性与另一个一加时间跨度值进行比较?
- javascript - 如何在html中按下按钮时触发Angular Mentions?
- reactjs - 如何在 react-chart-js-2 中使用填充 true 隐藏边框