Java/Android Developer.

0%

Kotlin androidExtensions findViewById缓存问题

Kotlin Android Extensions用的肯定很爽,少了一堆findViewById的编写,插件本身为我们生成代码,并且还会缓存起来,通过调用_$_findCachedViewById代替,避免频繁调用findViewById,看起来方便又高效,实际上有一个需要注意的点被忽略

0x01 缓存问题

在实际项目中,往往不止在ActivityFragment里面用到该插件,更多的会是在列表里面的item去使用,比方说RecyclerViewViewHolder,往往只是这样写

1
2
holder.itemView.textView1.text = "text1"
holder.itemView.textView2.text = "text2"

看上去跟Activity调用的方式差不多,只是需要通过具体的itemView去访问到具体的textView1,应该没什么问题,但是当把kotlin代码转成Java代码后,看到的是这样的情况

1
2
TextView var24 = (TextView)var3.findViewById(id.textView1);
var24.setText("text1")

可以看到并没有使用cache,也就是_$_findCachedViewById,当我改成调用两次

1
2
holder.itemView.textView1.text = "text1"
holder.itemView.textView1.textSize = 16f

则会

1
2
3
4
TextView var24 = (TextView)var3.findViewById(id.textView1);
var24.setText("text1")
var24 = (TextView)var3.findViewById(id.textView1);
var24.setTextSize(14f)

竟然调用了两次findViewById

0x02 缓存问题解决

当在这种需要通过view去获取字view再去操作的情况下,官方其实后来给了一个解决方案

  • LayoutContainer

需要额外再build.gradle配置

1
2
3
androidExtensions {
experimental = true
}

然后将需要的类实现LayoutContainer接口

1
2
3
4
5
6
class ViewHolder(override val containerView: View) : RecyclerView.ViewHolder(containerView), LayoutContainer {
fun setup() {
textView1.text = "text1"
textView1.textSize = 16f
}
}

这下再来看看编译后的代码

1
2
3
4
TextView var24 = (TextView)this._$_findCachedViewById(id.textView1);
var24.setText("text1")
var24 = (TextView)this._$_findCachedViewById(id.textView1);
var24.setTextSize(14f)

0x03 待续