Reputation: 469
My Android library contains ~1300 drawables. For server driven UI, applications need to efficiently retrieve each drawable using a backend specified string ID (assume it's the resource name for simplicity). There's separate logic for retrieving images from fallback URLs, the goal here is return an image instantly if we have it, rather than look it up. I can easily generate and include a kotlin source mapping in the library, e.g.
@DrawableRes fun toImageId(name:String):Int {
return when(name) {
"image_one" -> R.drawable.image_one
"image_two" -> R.drawable.image_two
...
"image_thirteen_hundred" -> R.drawable.image_thirteen_hundred
}
However I don't want to this mapping to prevent R8/Proguard from shrinking images that aren't used anywhere else. Otherwise several apps will unacceptably increase in size. As far as I can tell there isn't a way to exclude a source file from consideration of what resources are used. Many posts, like this one, recommend retrieving the asset directly through the resource name i.e.
resources.getIdentifier(resIdName, "drawable", packageName)
which does evade detection by resource shrinking, but is extremely slow. A unit test retrieving a single resource takes about 2 seconds. A test retrieving all the IDs takes almost 4 seconds.
Is there another viable approach to this problem?
EDIT: @CommonsWare is correctly points out that the actual in-app performance of getIdentifier() is orders of magnitude better than in unit tests. Effectively making it a non-issue.
Upvotes: 0
Views: 86