如何告诉 multidex 保留 jar 属性文件?

Posted

技术标签:

【中文标题】如何告诉 multidex 保留 jar 属性文件?【英文标题】:How can I tell multidex to keep a jar properties file? 【发布时间】:2019-03-16 20:11:11 【问题描述】:

我有一个我很确定与multidex 相关的问题。基本上,我使用的其中一个库在 jar 中有一个 .properties 资源包。随着我的应用程序开始增长,我开始遇到问题。我过去曾发过几篇关于它的帖子,但从未有任何解决方案(post 1、post 2)。 Post 2 实际上有更多关于这个问题的细节。

除非我强制该 Jar 上的某些代码在 Application onCreate 方法上运行,否则该资源基本上会丢失。至少这是直到昨天的问题。

昨天我更新了一个与此无关但现在比以前更大的 jar(我假设这意味着它有更多方法),现在代码在同一问题上再次失败 java.util.MissingResourceException: Can't find bundle for base name javax.servlet.LocalStrings, locale en_US但现在它对每个人都失败了,而不仅仅是一些用户。

我使用 apktool 将 apk 拆开,一个可以工作,一个不能工作(基本上是降级那些不相关的 jar),两个 apk 中都有一个 unknown 文件夹,但工作的那个文件夹中有 LocalStrings.properties文件夹和不起作用的文件夹中没有它们。我解压缩了那些不相关的 jar 以确保它们没有 javax.servlet 包,它们是 jar,所以它们没有任何其他可能影响 gradle 构建的东西。

基本上我现在的理论是这些 jar 足够大,可以将 javax.servlet 的东西从第一个 dex 文件中推出,但这并不完全正确,因为 properties 文件甚至不进入.dex 文件。如果我只是解压缩 apk,我可以看到根文件夹上的 javax 包和正确位置内的资源文件,但看不到 LocalStrings.properties 而如果我为一个有效的 apk 这样做,我可以看到 LocalStrings.properties 在那里。

现在我一直在测试multiDexKeepProguard,我得到了所有javax.servlet 进入主dex 文件,但我仍然无法让LocalStrings.properties 出现在apk 中,即使有:

-keepclassmembers class **$Properties

我还尝试了一些其他疯狂的事情,例如使用 javax.servlet 包将 LocalStrings.properties 文件放入我的主应用程序包中,但它也没有帮助。

那么我还能尝试什么?这是一个错误还是我做错了什么?

谢谢。

编辑:我想报告我通过删除不再使用的依赖项(广告网络)再次解决了这个问题。当我使用 dex2smali 查看第一个 dex 文件并看到它存在时,我意识到我仍然有这种依赖关系。因此,它放在第一个 dex 文件上的 jar 的大小肯定是个问题。

编辑:我的 proguard 设置中有这个:

-keep class javax.** *;
-keep interface javax.** *;
-keepclassmembers class javax.** *;
-keepclassmembers class **$Properties

【问题讨论】:

【参考方案1】:

不确定这是否是正确的做法,但显然 proguard 错误地为我删除了 *.properties 文件。

在构建时修复了什么

minifyEnabled false

然后返回

minifyEnabled true

之后,*.properties 文件在最终构建中再次可用。

【讨论】:

【参考方案2】:

您的包属性文件似乎已被 ProGuard 剥离。我不确定您是否尝试过以下配置

-keep class javax.servlet.** 

-keep class javax.servlet.**  *; 

-optimizations !javax.servlet
-dontoptimize

另外,还有更多参考资料:

缩码:https://developer.android.com/studio/build/shrink-code 处理资源文件:https://docs.huihoo.com/proguard/manual/examples.html -keeppackagenameshttps://***.com/a/5866755/8034839 How to tell ProGuard to keep everything in a particular package?

【讨论】:

谢谢。我确实有那些在proguard,只有我没有的东西是-optimizations !javax.servlet-dontoptimize,我猜我希望它优化所以我希望这不是问题。一旦我能重现问题,我会尽快测试这些。昨天我删除了一个广告网络并解决了这个问题,今天阅读它并做同样的事情仍然没有重现问题,我什至回到 git 并检查了旧的提交,但仍然没有重现它。另外我确实想补充一点,无论这些东西是否修复它,如果没有这两个东西,这大部分时间都是有效的。

以上是关于如何告诉 multidex 保留 jar 属性文件?的主要内容,如果未能解决你的问题,请参考以下文章

读取 JAR 文件外的属性文件

重复类 MultiDex$V14.class

如何告诉 ProGuard 保留用于 onClick 的函数?

如何告诉 proguard 保留枚举常量和字段

android MultiDex multidex原理下超出方法数的限制问题

如何告诉 M2Eclipse 将 jar 文件安装为 maven 依赖项