【问题标题】:Why this strange behaviour of the `by lazy` delegate in fragments为什么'bylazy'委托在片段中的这种奇怪行为
【发布时间】:2018-08-17 12:44:25
【问题描述】:

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

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

当从片段(包含对惰性委托获得的视图的引用的片段)前进然后返回(我使用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

 }

提前致谢

【问题讨论】:

    标签: android android-fragments kotlin android-lifecycle


    【解决方案1】:

    Fragment 的视图在被删除时会被破坏 - 但 lazy 字段不会清除它们的引用,因此它们实际上是在泄漏之前的视图。

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

    如果您能够直接使用kotlin extensions,它会在片段视图被自动销毁时生成查找、缓存和清除视图缓存的代码。

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

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

    【讨论】:

    • 我实际上正在使用它们,detailContaner1detailContainer2 是使用 kotlinx.synthetic 导入的,另外,我知道我不应该有相同的 id,但是出现了问题,因为我是在同一屏幕内重复使用两次 (<include ... />) 布局。无论如何,缓存实际上可能是问题所在,因为对于github.com/JetBrains/kotlin/blob/master/libraries/stdlib/jvm/… 中的SynchronizedLazyImpl,该值已经初始化。
    • @Jibbo 我已经编辑了可能的解决方案,它将从缓存中获取视图而不是泄漏旧视图。
    猜你喜欢
    • 2013-09-14
    • 1970-01-01
    • 1970-01-01
    • 2018-06-29
    • 2020-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多