After upgrading the Gradle plugin to 4.2.0 (before that, I didn't have this problem), it seems the names of XML resource files are changed when building a release build, for instance from res/xml/settings_master_switch_1.xml
to res/cb1.xml
.
This presents a problem with a library I wrote, since it takes the name of a resource given in xml, for instance
<com.smp.masterswitchpreference.MasterSwitchPreference
..
app:ms_includedPrefScreen="@xml/settings_master_switch_1" />
and looks up the resource id with this function
fun resInt(resName: String?, type: String): Int? {
resName ?: return null
val f = File(resName).nameWithoutExtension
return context.resources.getIdentifier(f, type, context.packageName)
}
The consumer of this library can simply have
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
or even with minifyEnabled false
to generate the problem.
The library with demo app can be found here https://github.com/svenoaks/MasterSwitchPreference
So I assume I must add some type of R8/Proguard or Gradle setting in consumer of this library to not change the name of the xml resource? What would this rule be?
I've tried both defining the resources to keep in res/raw/keep.xml
of the consumer app -
<resources xmlns:tools="http://schemas.android.com/tools"
tools:keep="@xml/settings_master_switch_1,@xml/settings_master_switch_2,@drawable/ic_baseline_cake_24.xml" />
and this rule in the proguard-rules.pro
-verbose
-keepattributes InnerClasses
-keep class **.R
-keep class **.R$* {
<fields>;
}
without success, the plugin renames the XML resources anyway.
In my case all I needed to do was change the attr declaration from integer to string:
<attr name="ms_includedPrefScreen" format="string"/>
<attr name="ms_excludedPrefScreen" format="string"/>
and remove the "@" annotation from the consumer, so that a literal string with the correct name is passed in:
app:ms_includedPrefScreen="xml/settings_master_switch_1"