Android _ ViewBinding 与 Kotlin 委托双剑合璧,从思维图到基础再到深入

<LinearLayout

tools:viewBindingIgnore=“true” >

3.2 创建绑定类

有三个创建绑定类的 API:

fun bind(view : View) : T

fun inflate(inflater : LayoutInflater) : T

fun inflate(inflater : LayoutInflater, parent : ViewGroup?, attachToParent : Boolean) : T

  • 1、在 Activity 中使用

MainActivity.kt

class TestActivity: AppCompatActivity(R.layout.activity_test) {

private lateinit var binding: ActivityTestBinding

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

binding = ActivityTestBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.tvDisplay.text = “Hello World.”
}
}

  • 2、在 Fragment 中使用

TestFragment.kt

class TestFragment : Fragment(R.layout.fragment_test) {

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

override fun onViewCreated(root: View, savedInstanceState: Bundle?) {
_binding = FragmentTestBinding.bind(root)

binding.tvDisplay.text = “Hello World.”
}

override fun onDestroyView() {
super.onDestroyView()

_binding = null
}
}

3.3 避免内存泄露

这里有一个隐藏的内存泄露问题,你需要理解清楚(严格来说这并不是 ViewBinding 的问题,即使你采用其它视图绑定方案也要考虑这个问题)。

问题:为什么 Fragment#onDestroyView() 里需要置空绑定类对象,而 Activity 里不需要? 答:Activity 实例和 Activity 视图的生命周期是同步的,而 Fragment 实例和 Fragment 视图的生命周期并不是完全同步的,因此需要在 Fragment 视图销毁时,手动回收绑定类对象,否则造成内存泄露。例如:detach Fragment,或者 remove Fragment 并且事务进入返回栈,此时 Fragment 视图销毁但 Fragment 实例存在。关于 Fragment 生命周期和事务在我之前的一篇文章里讨论过:Android | Fragment 核心原理 & 面试题 (AndroidX 版本)

总之,在视图销毁但是控制类对象实例还存活的时机,你就需要手动回收绑定类对象,否则造成内存泄露。

3.4 ViewBinding 绑定类源码

反编译如下:

public final class ActivityTestBinding implements ViewBinding {
private final ConstraintLayout rootView;
public final TextView tvDisplay;

private ActivityTestBinding (ConstraintLayout paramConstraintLayout1, TextView paramTextView)
this.rootView = paramConstraintLayout1;
this.tvDisplay = paramTextView;
}

public static ActivityTestBinding bind(View paramView) {
TextView localTextView = (TextView)paramView.findViewById(2131165363);
if (localTextView != null) {
return new ActivityMainBinding((ConstraintLayout)paramView, localTextView);
}else {
paramView = “tvDisplay”;
}
throw new NullPointerException("Missing required view with ID: ".concat(paramView));

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值