绑定和_绑定有什么区别?

Sar*_*ewi 5 android kotlin android-databinding android-viewbinding

我试图了解片段中视图绑定的实现,我发现它与活动不同。

在一次活动中:

private lateinit var binding: ResultProfileBinding

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = ResultProfileBinding.inflate(layoutInflater)
    val view = binding.root
    setContentView(view)
}
Run Code Online (Sandbox Code Playgroud)

在一个片段中:

private var _binding: ResultProfileBinding? = null
private val binding get() = _binding!!

override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    _binding = ResultProfileBinding.inflate(inflater, container, false)
    val view = binding.root
    return view
}

override fun onDestroyView() {
    super.onDestroyView()
    _binding = null
}
Run Code Online (Sandbox Code Playgroud)

现在我的问题是,为什么片段中有bindingand ?_binding这条线是做什么的,它的目的是什么?

private val binding get() = _binding!!
Run Code Online (Sandbox Code Playgroud)

Hen*_*ist 4

在第二个示例中,该_binding属性可以为空,以便允许在“初始化”之前进入状态。binding然后,假设支持字段 ( _binding) 已初始化,则该属性有一个 getter 来提供方便的访问。

您所指的特定行意味着当您尝试访问时binding,它将返回_binding。然而,空断言运算符( )添加了非空的!!额外断言。_binding

实际上,您所做的一切都是创建了 Lateinit 属性的类似物,实际上,如果您查看 Lateinit 声明的反编译字节码,它们实际上是相同的。

然而,正如 @Tenfour04 指出的,这里的细微差别是第二种方法允许您将支持字段设置回 null,而您不能使用属性来执行此操作lateinit。当您在片段中使用绑定时,建议将绑定清空以onDestroyView避免内存泄漏,因此这就是他们在片段中采用这种方法的原因。

  • `lateinit` 比单独的 `!!` 强制属性更安全,因为您不会意外得到 NullPointerException。使用单独的“!!”强制属性,您必须小心不要在片段被销毁后可能被调用的回调中使用它。Google 建议使用“!!”强制属性,以便您可以在视图被销毁时将支持绑定属性更改回 null。这可以防止绑定中的视图在片段分离期间“暂时”泄漏。 (2认同)