Kotlin androidExtensions findViewById缓存问题
September 26, 2019
Kotlin Android Extensions用的肯定很爽,少了一堆findViewById的编写,插件本身为我们生成代码,并且还会缓存起来,通过调用_$_findCachedViewById代替,避免频繁调用findViewById,看起来方便又高效,实际上有一个需要注意的点被忽略
0x01 缓存问题
在实际项目中,往往不止在Activity或Fragment里面用到该插件,更多的会是在列表里面的item去使用,比方说RecyclerView的ViewHolder,往往只是这样写
holder.itemView.textView1.text = "text1"
holder.itemView.textView2.text = "text2"看上去跟Activity调用的方式差不多,只是需要通过具体的itemView去访问到具体的textView1,应该没什么问题,但是当把 kotlin 代码转成 Java 代码后,看到的是这样的情况
TextView var24 = (TextView)var3.findViewById(id.textView1);
var24.setText("text1")可以看到并没有使用 cache,也就是_$_findCachedViewById,当我改成调用两次
holder.itemView.textView1.text = "text1"
holder.itemView.textView1.textSize = 16f则会
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配置
androidExtensions {
    experimental = true
}然后将需要的类实现LayoutContainer接口
class ViewHolder(override val containerView: View) : RecyclerView.ViewHolder(containerView), LayoutContainer {
    fun setup() {
        textView1.text = "text1"
        textView1.textSize = 16f
    }
}这下再来看看编译后的代码
TextView var24 = (TextView)this._$_findCachedViewById(id.textView1);
var24.setText("text1")
var24 = (TextView)this._$_findCachedViewById(id.textView1);
var24.setTextSize(14f)0x03 待续
— Evil Mouth