升级 Gradle 插件后,在发布版本中更改了 XML 资源名称

问题描述

Gradle 插件升级到 4.2.0 后(在此之前,我没有这个问题),似乎在构建发布版本时 XML 资源文件名称发生了变化,例如从 res/xml/settings_master_switch_1.xmlres/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 资源。

解决方法

通常人们可能希望保留类 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 声明从整数更改为字符串:

LocalSettings.php

并从消费者中删除“@”注释,以便传入具有正确名称的文字字符串:

   <attr name="ms_includedPrefScreen" format="string"/>
        <attr name="ms_excludedPrefScreen" format="string"/>