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