繁体   English   中英

具有合成绑定和可空性的 Kotlin 视图

[英]Kotlin views with synthetic binding and nullability

我注意到当使用 Kotlin 的合成绑定时,返回的视图是非空的(Kotlin 将返回View! )。 但这对我来说意义不大,因为findCachedViewById实际上可以返回空结果,这意味着视图实际上可以为空。

public View _$_findCachedViewById(int var1) {
  if(this._$_findViewCache == null) {
     this._$_findViewCache = new HashMap();
  }

  View var2 = (View)this._$_findViewCache.get(Integer.valueOf(var1));
  if(var2 == null) {
     View var10000 = this.getView();
     if(var10000 == null) {
        return null;
     }

     var2 = var10000.findViewById(var1);
     this._$_findViewCache.put(Integer.valueOf(var1), var2);
  }

  return var2;
}

那么为什么在这种情况下它们不是可选的呢? 为什么 Kotlin 不直接返回View? 使用合成绑定时,开发人员在处理视图时将被迫检查可空性?

也许这只是因为我是 Kotlin 的新手,但我认为这有点违反直觉,因为变量不是可选的,但我们仍然应该检查视图是否实际上不为空。

那么在这种情况下,像下面的代码那样做有意义吗?

view?.let {
    // handle non null view here
}

我想通了,我总是在发布我的问题后立即找到正确的 SO 问题:)

View后面的单个感叹号实际上并不意味着视图不能像我预期的那样为 null。

This answer to another question基本上回答了我的确切问题。 View在使用合成绑定时实际上可以为 null,但我们无法确定,因此只有一个感叹号。

因此,可以安全地假设我在上面发布的代码 - 使用?.let{...}是处理视图的完全可接受的方式,当您不确定它们在访问它们时是否已经初始化时。

视图可能为空的情况非常罕见,但它可能会发生。

正如您已经指出的那样,单个感叹号并不意味着它不是空的,而是它是一种 Java 平台类型,编译器不知道它是否可以为空。

我认为你的建议很好,尽管它在 null 的实际情况下默默地失败了,这实际上可能不是你想要的。

假设您试图在 onCreateView 中调用您的视图,但忘记了它尚未初始化。 该片段不会按预期运行,但不会产生有意义的错误来帮助您调试问题。

我仍在尝试自己解决一个或另一个解决方案,但我建议要么显式处理 null 的情况:

view?.let {
    //...
} ?: throwExceptionIfDebugElseLogToCrashlytics()

或者决定这次你真的希望它抛出 NullPointerException 在这种情况下我建议:

view!!.let {
    //...
}

后者不会因为“应该”是不可能的边缘情况而使您的代码膨胀,并且它不会悄无声息地失败,但它仍然让读者清楚地知道视图可能为空。 显然,。 编译器不需要,它只是为了使处理平台类型的选择策略更加明确。

如果您尝试在活动或视图的上下文之外或在 lambda 中从侦听器访问视图,则合成视图绑定实际上可能会发生空指针异常。

问题出在 lambda 中,Frantisek 在这里发布了相关信息:https ://stackoverflow.com/posts/comments/115183445?noredirect=1

这个想法是 Android 中的 xml 布局是相当静态的,为了使用合成视图,您必须创建一个已解析布局的直接导入:

import kotlinx.android.synthetic.main.activity_main.*

因此,在现实生活中,不存在View为空的非魔法场景。 除非你选择了错误的合成布局,否则你会在第一次运行时崩溃。

也就是说,如果您在运行时修改视图、删除Views等,它当然会中断。但同样,这不是合成Views的默认用法,需要不同的方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM