Android、Scala 和 Proguard

Posted

技术标签:

【中文标题】Android、Scala 和 Proguard【英文标题】:Android, Scala and Proguard 【发布时间】:2011-12-03 23:35:08 【问题描述】:

在遇到与 android 命令行工具集的排列一样多的问题后,我终于设法将 Scala 和 Java 源代码的混合编译成一个可用的 apk。

正如许多人建议的那样,我使用proguard 通过dex 工具来压缩Scala 库。问题是这样的:

BUILD SUCCESSFUL
Total time: 1 minute 29 seconds

一分半钟。我们在这里讨论的是具有 Hello-World 复杂性的应用程序。我不认为我可以那样发展。我需要参加冥想课程。

这是proguard 配置:

-injars $out.absolute.dir/classes:$scala-library.jar(!META-INF/MANIFEST.MF,!library.properties)
-outjars $out.absolute.dir/classes.min.jar
-libraryjars $android.jar
-dontwarn
-dontoptimize
-dontobfuscate
-keep public class * extends android.app.Activity

有没有办法加快proguard步骤?

编辑:我在一个相当不错的双核、3GB 内存机器上运行它,在 64 位 Linux 之上。 ant compile (scalac/javac) 的运行需要 3 秒。如上所述,完整的ant install 需要 1:30。根据输出,这是“冻结”的proguard 步骤,很可能是因为 scala/android 运行时库的大小。

【问题讨论】:

我们需要更多细节,例如您的机器设置..即 cpu、ram 等的数量。 假设编译器会成为你使用的编译器的瓶颈? 另见:proguard.sourceforge.net/manual/examples.html#scala。我认为这不是编译器的瓶颈,而是 8.5 Mb 的 scala 运行时需要相当长的时间来读取和打包。 您不需要在测试运行中执行 proguard 步骤。只要模拟器可以处理大尺寸,您也可以避免使用 proguard 进行测试。 @Daniel - 遗憾的是,proguard 始终是必需的 - 库太大而无法适应 Dalvik 的“dex”文件格式 :-( 这对于模拟器和真实设备一样适用。而且您应该知道 2.9.1 根本没有明智的解决方案 :-( 请参阅 groups.google.com/group/scala-debate/browse_thread/thread/… 了解原因。 【参考方案1】:

通过 android Ant 构建工作可能不是解决此问题的正确方法。

当前的“最佳建议”是将 SBT 与

proguard (https://github.com/siasia/xsbt-proguard-plugin) 和 安卓 (https://github.com/jberkel/android-plugin)

插件。

【讨论】:

同意。但请注意我在上面的评论中提到的 2.9.1 的问题。可以在设备上安装 Scala (2.8.x) 库并避免 proguard 步骤,如下所述:zegoggl.es/2011/07/… 但请注意,大多数情况下存在一些问题(据我所知尚未修复) Android SDK 的最新版本。 我还没有尝试过 SBT,但我不明白它会有什么帮助。它不会自动执行我手动安排的相同 proguard 运行吗? 请注意,proguarding 现在是 sbt android 插件的一部分(不要害怕它显示的误导性和不正确的许可证消息,请参阅 github.com/jberkel/android-plugin/issues/129)【参考方案2】:

ProGuard 缩小 Scala 2.9.1 库比 Scala 2.8.1 库需要更长的时间(54 秒对 13 秒,8.5 MB 对 6.2 MB)。要么是库类的结构发生了根本性的变化,要么是一些新的类导致了过多的计算。我必须弄清楚是否可以针对这种情况改进 ProGuard 或其配置。目前,您或许可以使用 Scala 2.8.1。

我假设您的 ProGuard 配置还包含 Android 和 Scala 所需的选项,如 ProGuard manual 中所述。如果您使用的是常规的 Android 构建过程,则在 Ant 构建文件中已经为您指定了输入(classeslibs)和库(android.jar),您无需在ProGuard 配置文件。阅读它们两次只需要时间并产生许多警告(您已完全关闭它们 - 有选择地关闭它们更安全)。

【讨论】:

尽管花费了更长的时间,但我在使用 Proguard 和 Scala 2.9.1 时遇到了奇怪的问题。混淆后,shrinkin 会删除基本的 scala 内容,例如 Traversable 或 HashMap.foreach 等。因此,它会导致程序因 ClassNotFoundError 类 axy (等)而失败,proguard_map 将 axy 指向上述和使用的 Scala 对象。 @vertti 一个经过处理的 HelloWorld 程序(结合 Scala 2.9.1)在我尝试时运行良好,所以我需要有关您的代码的更多详细信息。如果您在此处或 ProGuard 的帮助论坛中发布单独的问题,我会进行调查。 谢谢,我会试试的,但我目前的游戏大约有 6000 行 scala 并且撕掉仍然会破坏 proguard 的功能部分可能会很困难。 感谢您的帮助(在 proguard bug tracker)。对其他人:我的问题原来与 Windows 文件系统有关,而不是 Scala(请参阅最后一个条目:proguard.sourceforge.net/manual/limitations.html) 看这个:scalandroid.blogspot.com/2012/03/… - Scala 2.10 将再次与 proguard 一起摇滚【参考方案3】:

如果您有一部已root 的手机并且只想对此进行测试,您可以直接在手机上安装 scala 库,这样您就不再需要 proguard 步骤了:

https://github.com/jrudolph/scala-android-libs

【讨论】:

以上是关于Android、Scala 和 Proguard的主要内容,如果未能解决你的问题,请参考以下文章

intellij 与 sbt scala 和 android dev

android + scala + 混淆代码

我们如何在 Scala 中使用 android JobIntentService?

使用 scala 和 android-plugin 的 Proguard:java.lang.StringIndexOutOfBoundsException:字符串索引超出范围:160

使用 scala sbt 构建一个独立的 jar 以合并到一个 android 项目中

如何将 Scala 集成到核心 Android 平台中?