How to get identifier for a resource inside Android dynamic module?

933 views Asked by At

I am working on Dynamic Module Feature Delivery and i have some drawable resources inside the dynamic module as well. The problem i am facing is that i cannot get identifiers for the resources however if i directly reference any of them then it works well. So the problem occurs only while trying to access the resource identifiers. Currently i am trying to do it like this :

val resID = resources.getIdentifier("drawable_name", "drawable",packageName)

and this

val resID = resources.getIdentifier("drawable_name", "drawable","explicit package name of module") 

However when i access a drawable directly like R.drawable.mydrawable, then it works. Please guide me as to how can i access the resource identifiers because currently its returning 0 every time which means it is unable to access the identifier.

3

There are 3 answers

1
DragonCatHan On

Try adding .modulePluginName as suffix to your packageName.

Eg. Your packageName is com.android.test, and your dynamic module name is moduleHello. Then set pluginPackageName = "com.android.test.moduleHello".

Like this to access resources:

val resID = resources.getIdentifier("drawable_name", "drawable",pluginPackageName)
0
Allan Veloso On

If you got this resources object from an activity in :app it's no surprise that there is no identifiers from an dynamic module that was loaded after its creation.

If you just need a few identifiers, like for navigation, you can define the identifiers in the :app module with the @+id/, then they will be available on the feature module xmls with the @id and in your classes with the R.id.

If you want the ID to get a resource, you can do with URI.Builder like explained in this documentation.

Or like in the sample of dynamic feature, create a new context that will have the resources, assets, and etc. of your installed module:

 context.createPackageContext("explicit.name.of.package.module.here", 0).also { SplitCompat.install(it) }

In this resources you can get assets dynamically loaded, including language resources. See this documentation

Notice that you have to call that after your dynamic module was loaded. You can use a listener for that.

I didn't tested the later way, but it's in the official Android dynamic module samples. Let us know if it worked for you.

If you need the IDs for instrumented tests like Expresso, it's even simpler, add to your :app module the feature module as dependence (yes, you can as androidTestImplementation dependency!):

androidTestImplementation(project(":my_dynamic_feature"))

Lastly, R.drawable.mydrawable is the identifier. It's a int, you can see it in your apk classes.dex.

Explain better what is your use case, but at least one of the above should satisfy your needs.

0
Leandroid On

I was able to solve this by replacing the packageName for the feature-module package name.

App package name: com.example.my_app_package
Feature's resources package name: com.example.my_app_package.my_dynamic_feature

I'm not sure exactly from where the value my_dynamic_feature is obtained, but the full package will not be the one that you defined on the module's build.gradle applicationId or AndroidManifest package property.