Android App Bundle: Load Drawable Resources From Dynamic Feature Modules

Nov 18, 2019

Refer to Launch Activity from Dynamic Feature Modules for setup.

I am using getQuoteMakerModule code from Load Dynamic Feature Modules with ViewModel and Helper Class to load a dynamic feature module.

class DailyQuoteActivity : AppCompatActivity() {    private val viewModel by viewModels<DailyQuoteViewModel>()    override fun attachBaseContext(base: Context) {        // if need to access language resources from dynamic modules        /*        val configuration = Configuration()        configuration.setLocale(Locale.forLanguageTag("en"))        val context = base.createConfigurationContext(configuration)        super.attachBaseContext(context)         */        super.attachBaseContext(base)        // required to access resources (e.g. drawable) from dynamic modules        SplitCompat.install(this)    }    fun loadDrawableFromModule() {        viewModel.getQuoteMakerModule { success ->            if (success) {                // a resource id from dynamic modules                val moduleResourceId = ...                if (viewModel.needSplitCompatInstall) {                    Timber.d("SplitCompat.install")                    // you can access drawable via applicationContext without SplitCompat.install                    val d = AppCompatResources.getDrawable(applicationContext, moduleResourceId)                    // should be able to access resources via a new context                    val newContext = context.createPackageContext(context.packageName, 0)                    val d2 = AppCompatResources.getDrawable(newContext, moduleResourceId)                    // need this to access drawable from module during first install                    SplitCompat.install(context)                    viewModel.needSplitCompatInstall = false                }                // access drawable via activity context require SplitCompat.install                // , else Resources.NotFoundException exception is thrown                val d = AppCompatResources.getDrawable(context, moduleResourceId)                imageView.setImageResource(moduleResourceId)            }        }    }}

More about Resources

You can save resources id of dynamic feature module in database

val resourceId = R.drawable.sticker_cool

I am not sure how reliable is the resource id (as in whether the id would remain persistent between compilation). A safer method would be to save the resource name.

val resourceName = resources.getResourceEntryName(R.drawable.sticker_cool) // "sticker_cool"

You can get the resource id of the Dynamic Feature Modules' resources via name in Base Module

val baseModulePackage = "com.luasoftware.nuanxin"val dynamicModuleName = "quotemaker"val packageName = "$baseModulePackage.$dynamicModuleName"val resourceId = resources.getIdentifier("sticker_cool", "drawable", packageName)

NOTE: Note that the packageName for dynamic feature module is pretty tricky (the actual package name for my dynamic feature module is com.luasoftware.quotemaker while the module name is quotemaker).

❤️ Is this article helpful?

Buy me a coffee ☕ or support my work via PayPal to keep this space 🖖 and ad-free.

Do send some 💖 to @d_luaz or share this article.

✨ By Desmond Lua

A dream boy who enjoys making apps, travelling and making youtube videos. Follow me on @d_luaz

👶 Apps I built

Travelopy - discover travel places in Malaysia, Singapore, Taiwan, Japan.