如何强制 Proguard 保留我的 .xml 资源文件?

Posted

技术标签:

【中文标题】如何强制 Proguard 保留我的 .xml 资源文件?【英文标题】:How can I force Proguard to keep my .xml resource file? 【发布时间】:2011-08-16 11:11:29 【问题描述】:

我成功地将 proguard 用于我的 android 应用程序。

但是,我在使用一个应用时遇到了问题。

此应用程序使用一个 java 库,该库具有一个存储在包中的 .xml 文件。

InputStream istream = Library.class.getResourceAsStream("resource.xml");

当 proguard 被禁用时,这个库工作得很好。但是,运行proguard,似乎xml文件被完全剥离了。

相关的proguard.cfg

-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
#-dontobfuscate
#-repackageclasses '' //THIS IS DISABLED
-keepattributes *Annotation*
-keepattributes Signature
-verbose
-dontwarn roboguice.activity.RoboMapActivity
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

关于如何强制保留此 xml 文件的任何想法?

【问题讨论】:

【参考方案1】:

你应该在 res/raw 下添加一个新文件 keep.xml。

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
    tools:keep="@layout/l_used*_c,@layout/l_used_a,@layout/l_used_b*"
    tools:discard="@layout/unused2" />

在 tools:keep 中,您列出要保留的布局。如果您在代码中使用反射来获取您的可绘制对象,您甚至可以保留特定的可绘制对象

tools:keep="@drawable/ico_android_home_infosperso"

我更喜欢添加tools:shrinkMode="strict",这样我可以确保不会消除任何资源,除非它没有被确定使用。你可能想看看这个链接Shrink your code。 不要忘记将这些行添加到您的 proguard 规则中:

-keepattributes InnerClasses -keep class **.R -keep class **.R$* &lt;fields&gt;;

【讨论】:

【参考方案2】:

首先,原来使用ant和我的build.xml脚本根本没有处理.xml资源文件。您需要手动向 build.xml 添加复制操作,以便将资源文件复制到输出目录。

不过,在解决了这个问题后,proguard 还是把我的工作搞砸了。解决方案是:

 -keeppackagenames the.package.where.the.file.is.kept

这确保可以通过调用 Library.class.getResource 找到 .xml 文件。

【讨论】:

【参考方案3】:

您应该将文件存储在相应的/res/xml/res/assets/res/raw 文件夹中,并通过资源管理系统或资产管理器相应地访问它们。您可以在Android Developer's Guide 中阅读有关提供资源的更多信息。

【讨论】:

这很好,但这是一个 java 库中的 xml 文件,而不是 android 库。我在我的android应用程序中使用它,并且没有proguard它可以正常工作。我当然明白,在普通的安卓应用程序中你不会这样使用它。 问题是,它看起来不像是 ProGuard 的错。 ProGuard 不会从 JAR 中剥离资源,它只能在压缩期间删除类。这些问题更有可能源自 Android 构建文件。可以修改它们以满足您的需要,但这不是一个容易的想法。而且即使你成功了,每次 SDK 更新时,你都可能需要再做一次。 不过,当 proguard 被禁用时,资源在我的应用程序中工作。启用 proguard 后,它们不会。所以,proguard 是在做一些惹麻烦的事情。 您究竟是如何禁用 ProGuard 的?您的意思是根本没有在 build.xml 中调用它,或者您是否更改了它的配置文件以使其不会缩小、优化或混淆? 我在 build.properties 或其他属性文件中禁用它。无论如何,我找到了解决方案,并且在我的实现中也发现了一个错误。

以上是关于如何强制 Proguard 保留我的 .xml 资源文件?的主要内容,如果未能解决你的问题,请参考以下文章

Proguard 不会保留班级成员的枚举

如何排除一个类被proguard保留

ProGuard - 如何保留方法并同时混淆它们?

Proguard 保留 R 类

如何将枚举类型字段保留在 proguard 中?

如何告诉 ProGuard 保留私有字段而不指定每个字段