Update: Kotlin 1.1.4 has a fix!
Kotlin today announced the new 1.1.4 version which features an improvement for using Kotlin Android Extensions on custom views and View Holders. You can read more about the experimental proposal here: https://github.com/Kotlin/KEEP/blob/master/proposals/android-extensions-entity-caching.md
If you are still curious about the original article, please keep reading!
I am a big fan of the Kotlin Android Extensions as they helped me to get rid of copious amounts of boilerplate code.
Thanks to it you can access to views directly referencing them by the Id.
However while I was implementing a
ViewHolder I wanted to check how efficient is to use these extensions inside the bind method.
Here’s an example of a
ViewHolder that uses a
TextView using the Kotlin Android Extensions directly.
This apparently simple
ViewHolder becomes very expensive without realization. We can decompile the Kotlin code to Java to see what is happening under the hood.
Go to Tools > Kotlin > Show Kotlin Bytecode and then click on Decompile
itemView.title is actually performing
itemView.findViewById(R.id.title) and this is exactly what you want to avoid in a
Let’s move the call to
itemView.title to the class construction:
Now let’s take a look at the new Java decompiled code:
As you can see, the
findViewById is done on the constructor method and not on each
A little update: As Ihor Kucherenko pointed out, the KAE will keep a reference to the view after the first call, instead of using findViewById all the time. That works for Activities and Fragments. So you don’t need to worry about the problem presented here.
However still no support for a ViewHolder and similar patterns. There’s a solution proposal on this PR, which unfortunately has been open for a year:
It wasn’t 100% for me on the documentation if findViewById was being called once, always or never. Compared to ButterKnife, where the View binding only happens once, the Kotlin Android Extensions can be a source of performance issues if used incorrectly.
Be careful on those parts of code where performance matters, don’t be afraid of decompiling the Bytecode to Java to understand it better.