XML 升级 Gradle 插件后,资源名称在发布版本中发生了变化
XML resource names are changed in release builds after upgrading Gradle plugin
将 Gradle 插件升级到 4.2.0 后(在此之前,我没有遇到这个问题),似乎 XML 资源文件的名称在构建发布版本时发生了变化, 例如从 res/xml/settings_master_switch_1.xml
到 res/cb1.xml
.
这表明我编写的库存在问题,因为它采用 xml 中给定的资源名称,例如
<com.smp.masterswitchpreference.MasterSwitchPreference
..
app:ms_includedPrefScreen="@xml/settings_master_switch_1" />
并用这个函数查找资源id
fun resInt(resName: String?, type: String): Int? {
resName ?: return null
val f = File(resName).nameWithoutExtension
return context.resources.getIdentifier(f, type, context.packageName)
}
这个库的消费者可以简单地拥有
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
甚至 minifyEnabled false
也会产生问题。
可以在此处找到带有演示应用程序的库 https://github.com/svenoaks/MasterSwitchPreference
所以我假设我必须在该库的使用者中添加某种类型的 R8/Proguard 或 Gradle 设置才能不更改 xml 资源的名称?这条规则是什么?
我都尝试过定义要保留在消费者应用程序 res/raw/keep.xml
中的资源 -
<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" />
和 proguard-rules.pro
中的这条规则
-verbose
-keepattributes InnerClasses
-keep class **.R
-keep class **.R$* {
<fields>;
}
没有成功,插件重命名 XML 资源。
一般人可能想保留 class R
:
-verbose
-keepattributes InnerClasses
-keep class **.R
-keep class **.R$* {
<fields>;
}
但也可以注释,以保留特定资源:
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
tools:keep="@xml/settings_master_switch_1" />
在我的例子中,我需要做的就是将 attr 声明从整数更改为字符串:
<attr name="ms_includedPrefScreen" format="string"/>
<attr name="ms_excludedPrefScreen" format="string"/>
并从消费者中删除“@”注释,以便传入具有正确名称的文字字符串:
app:ms_includedPrefScreen="xml/settings_master_switch_1"
将 Gradle 插件升级到 4.2.0 后(在此之前,我没有遇到这个问题),似乎 XML 资源文件的名称在构建发布版本时发生了变化, 例如从 res/xml/settings_master_switch_1.xml
到 res/cb1.xml
.
这表明我编写的库存在问题,因为它采用 xml 中给定的资源名称,例如
<com.smp.masterswitchpreference.MasterSwitchPreference
..
app:ms_includedPrefScreen="@xml/settings_master_switch_1" />
并用这个函数查找资源id
fun resInt(resName: String?, type: String): Int? {
resName ?: return null
val f = File(resName).nameWithoutExtension
return context.resources.getIdentifier(f, type, context.packageName)
}
这个库的消费者可以简单地拥有
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
甚至 minifyEnabled false
也会产生问题。
可以在此处找到带有演示应用程序的库 https://github.com/svenoaks/MasterSwitchPreference
所以我假设我必须在该库的使用者中添加某种类型的 R8/Proguard 或 Gradle 设置才能不更改 xml 资源的名称?这条规则是什么?
我都尝试过定义要保留在消费者应用程序 res/raw/keep.xml
中的资源 -
<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" />
和 proguard-rules.pro
-verbose
-keepattributes InnerClasses
-keep class **.R
-keep class **.R$* {
<fields>;
}
没有成功,插件重命名 XML 资源。
一般人可能想保留 class R
:
-verbose
-keepattributes InnerClasses
-keep class **.R
-keep class **.R$* {
<fields>;
}
但也可以注释,以保留特定资源:
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
tools:keep="@xml/settings_master_switch_1" />
在我的例子中,我需要做的就是将 attr 声明从整数更改为字符串:
<attr name="ms_includedPrefScreen" format="string"/>
<attr name="ms_excludedPrefScreen" format="string"/>
并从消费者中删除“@”注释,以便传入具有正确名称的文字字符串:
app:ms_includedPrefScreen="xml/settings_master_switch_1"