android - 为什么 fragment 中 `by lazy` 委托(delegate)的这种奇怪行为

标签 android android-fragments kotlin android-lifecycle

几天前,我发布了this关于在屏幕中多次包含相同布局时使用合成属性的问题。

答案很棒,但在我多试了几天之后,我发现了一个奇怪的行为:

当从 fragment (包含对惰性委托(delegate)获得的 View 的引用的 fragment )前进然后返回时(我使用 transaction.commit()manager.popBackStack (), 执行此操作), 标签将为空。我已经用调试器检查过那里是否有任何东西是空的,但什么都没有。

似乎唯一可行的解​​决方案是将 by lazy 替换为 lateinit var 并在 onViewCreated 中分配它们。

你知道为什么吗?作为 kotlin 惯用语,我使用的解决方案仍然“好”吗?

为了完整起见,我包含了两段代码:

部分工作:

private val foundTitle by lazy { detailContainer1.title }
private val foundDescription by lazy { detailContainer1.description }

private val wantedTitle by lazy { detailContainer2.title }
private val wantedDescription by lazy { detailContainer2.description }

总是工作的一个:

 private lateinit var foundTitle: TextView
 private lateinit var foundDescription: TextView

 private lateinit var wantedTitle: TextView
 private lateinit var wantedDescription: TextView

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {

   foundTitle = detailContainer1.title
   foundDescription = detailContainer1.description

   wantedTitle = detailContainer2.title
   wantedDescription = detailContainer2.description

 }

提前致谢

最佳答案

Fragment 的 View 在被移除时会被销毁 - 但 lazy 字段不会清除它们的引用,因此它们实际上是在泄漏之前的 View 。

如果可能,您应该在您的项目中始终拥有唯一的 View ID,即使它们不在同一布局中 - 重复可能会导致多个问题(就像您的问题)。

如果您能够使用 kotlin extensions当fragments View 自动销毁时,它会直接生成用于查找、缓存和清除 View 缓存的代码。

尝试从 fragment 缓存中“获取” View ,而不是将它们分配给字段:

private val foundTitle 
    get() = detailContainer1.title
private val foundDescription
    get() = detailContainer1.description

private val wantedTitle
    get() = detailContainer2.title
private val wantedDescription
    get() = detailContainer2.description

关于android - 为什么 fragment 中 `by lazy` 委托(delegate)的这种奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51895742/

相关文章:

Android:如何在 TextView 中对齐文本?

android - 从Listview的onClick方法启动 Activity ( fragment )

java - 为什么 Android 中不缓存 JSON 异常?

android - Android Beacon Library真的支持后台扫描吗?

java - 如何在 fragment 中实现监听器接口(interface)?

java - Android 从fragment中获取tabLayout

android - 如何声明在 kotlin 伴随对象中声明的 native cpp 方法?

android - 为什么 MediaPlayer prepare() 不与流一起使用?

Android 文件选择器绝对路径问题

java - 如何使用接口(interface)从 Activity 回调回 fragment