使用 Scala 2.8 Trunk 构建面向 Android

发布于 2024-08-31 08:05:33 字数 385 浏览 4 评论 0原文

在 android 上使用 Scala 的明确参考似乎在这里: http://www.scala-lang .org/node/160

不幸的是,所有关于在 android 中使用 scala 的参考文献都基于 Scala 2.7 并引用了自定义构建 android-library.jar,其中有一些神秘的引用表明此自定义构建不是“更高版本的 android 不需要(我使用的是 2.1 / API v7)

那么...在 android 项目中使用 Scala 2.8 需要哪些步骤?最好使用 eclipse 和 Google 为该 IDE 提供的 Android 工具。

The definitive reference for using Scala on android seems to be here: http://www.scala-lang.org/node/160

Unfortunately, all the references on using scala with android are based around Scala 2.7 and refer to a custom build android-library.jar, with a couple of cryptic references suggesting that this custom build isn't needed for later versions of android (I'm using 2.1 / API v7)

So... What are the steps needed to use Scala 2.8 in an android project? Preferably using eclipse and the Android tools that Google supplies for that IDE.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

雨巷深深 2024-09-07 08:05:33

编辑:

我的新方法是使用我的 Eclipse 插件: https://github.com/banshee/AndroidProguardScala (自述文件包含安装说明和指向普通 Eclipse 更新站点的指针)。

旧的答案仍然有效,但新的方法更好。

[老办法]
我的方法:

  • 使用普通的 Android/eclipse 工具来创建 Java 项目。
  • 添加包含 Scala 代码的第二个项目。这样我就可以保留生成的代码以供将来参考(我对 Android 和 Scala 都是新手)。这个项目可以引用android.jar。
  • scala 项目生成一个在 java 项目中使用的 jar 文件
  • 使用 proguard 来剥离库。我相信这避免了对 2.7 中使用的 scala-android.jar 的需要,

但我还没有将它用于比 hello, world 更雄心勃勃的事情,所以将它更多地视为一组提示。

在 scala 项目中,我添加了一个构建器(Builder > New),它只是项目根目录中名为 pguard 的 shell 脚本,其中包含:

#!/bin/sh
cd $1
PROGUARD=$HOME/dev/proguard/lib/proguard.jar
LIBS=
OUTPUT=lib/proguard.jar
rm -f $OUTPUT
AJAR=/Users/jamesmoore/dev/android-sdk-mac_86/platforms/android-7/android.jar
# java -jar $PROGUARD -injars 'bin:lib/scala-library.jar(!META-INF/MANIFEST.MF,!library.properties)' -outjar $OUTPUT -libraryjars  @proguard.txt
java -Xmx1g -jar $PROGUARD -injars 'bin:lib/scala-library.jar(!META-INF/MANIFEST.MF,!library.properties)' -outjar $OUTPUT -libraryjars $AJAR @proguard.txt

构建器的位置设置为:

${build_project}/pguard

并且工作目录和参数都设置为

${build_project}

Also in the root scala 项目中,有一个 proguard 参数文件 @proguard.txt:

-dontwarn
-dontoptimize
-dontobfuscate
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,
                SourceFile,LineNumberTable,*Annotation*,EnclosingMethod
-keep public class com.banshee.** {
    public protected *;
}

当然,您需要更改 -keep 参数以保留您自己的代码。

在 java 项目中,我添加了 scala 项目生成的 jar 文件(我在上面的脚本中使用了 lib/proguard.jar)。

不过,不要将 scala 项目添加为 java 项目的构建路径中的必需项目。除了 jar 文件之外,这还会添加 scala 类文件并混淆 dex(因为它会同时获取 .class 文件和 jar 中的相同内容)。据我所知,Eclipse 将构建工作区中的所有内容,因此当您单击“执行”按钮时,两个项目都会构建。

Edit:

My new way of doing this is to use my Eclipse plugin: https://github.com/banshee/AndroidProguardScala (the readme has instructions for installing and a pointer to a normal Eclipse update site).

The old answer still works, but the new way is just better.

[The old way]
My approach:

  • Use the normal Android/eclipse tools for creating a Java project.
  • Add a second project containing the Scala code. That way I get to keep the generated code for future reference (I'm new at both Android and Scala). This project can reference android.jar.
  • The scala project produces a jar file that's used in the java project
  • Use proguard to strip the library. I believe this avoids the need for the scala-android.jar that was used in 2.7

I haven't used this for anything more ambitious than hello, world though, so take it as more of a set of hints.

In the scala project, I add a builder (Builder > New) that's just a shell script called pguard in the root directory of the project containing:

#!/bin/sh
cd $1
PROGUARD=$HOME/dev/proguard/lib/proguard.jar
LIBS=
OUTPUT=lib/proguard.jar
rm -f $OUTPUT
AJAR=/Users/jamesmoore/dev/android-sdk-mac_86/platforms/android-7/android.jar
# java -jar $PROGUARD -injars 'bin:lib/scala-library.jar(!META-INF/MANIFEST.MF,!library.properties)' -outjar $OUTPUT -libraryjars  @proguard.txt
java -Xmx1g -jar $PROGUARD -injars 'bin:lib/scala-library.jar(!META-INF/MANIFEST.MF,!library.properties)' -outjar $OUTPUT -libraryjars $AJAR @proguard.txt

The builder has Location set to:

${build_project}/pguard

And both working directory and arguments set to

${build_project}

Also in the root of the scala project, there's a proguard arguments file @proguard.txt:

-dontwarn
-dontoptimize
-dontobfuscate
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,
                SourceFile,LineNumberTable,*Annotation*,EnclosingMethod
-keep public class com.banshee.** {
    public protected *;
}

You'll want to change the -keep arguments to keep your own code, of course.

In the java project, I add the jar file that's produced by the scala project (I use lib/proguard.jar in the script above).

Don't add the scala project as a required project in the java project's build path, though. That will add the scala class files in addition to the jar file and confuse dex (since it'll get both the .class files and the same things in the jar). As far as I can tell, Eclipse will build everything in the workspace, so when you hit the go button, both projects get built.

我一直都在从未离去 2024-09-07 08:05:33

经过大量调查后,Proguard 确实对于将应用程序部署的大小和速度保持在合理的水平至关重要。

遗憾的是,没有合适的方法来嵌入 proguard 作为构建步骤。使用脚本可能是一种可能性,但我还需要支持 Windows、Linux 和 OSX 环境。

我也不确定双项目解决方案,因为它阻止 Scala 代码使用生成的资源文件 R.java,而我希望能够做到这一点。

最后,我能够使用 Scala 2.8 让 SBT 和 Ant 构建一个 android 2.1 应用程序。 Ant 是最受欢迎的最终解决方案,因为它与 Android 的 eclipse 插件使用相同的文件组织。我在这里写下了解决方案: http://scala-ide .assembla.com/wiki/show/ae55a-oWSr36hpeJe5avMc/Developing_for_Android

然后,Eclipse 启动 Ant 作为外部工具来打包和安装应用程序。

After much investigation, it really does look like Proguard is essential to keep the size and speed of deploying the application to reasonable levels.

Sadly, there is no suitable way to embed proguard as a build step. Using scripts might be a possibility, but I also need to support Windows, Linux and OSX environments.

I was also unsure about the twin-project solution, as it prevented Scala code from using the generated resources file R.java, which I wanted to be able to do.

In the end, I was able to make both SBT and Ant build an android 2.1 application using Scala 2.8. Ant was the favourite final solution as it works with the same file organisation as Android's eclipse plugin. I've written up the solution here: http://scala-ide.assembla.com/wiki/show/ae55a-oWSr36hpeJe5avMc/Developing_for_Android

Eclipse then launches Ant as an external tool to package and install the application.

贵在坚持 2024-09-07 08:05:33

我现在使用对之前答案的修改来在 Windows 上运行:只需将所有内容移至 @proguard_windows.txt,这样您就不必担心作为脚本运行。

我的新 @proguard_windows.txt 如下所示:

-injars bin;lib/scala-library.jar(!META-INF/MANIFEST.MF,!library.properties)

-outjar gen/scandroid.jar

-libraryjars lib/android.jar

-dontwarn
-dontoptimize
-dontobfuscate
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers

-keepattributes Exceptions,InnerClasses,Signature,Deprecated,
                SourceFile,LineNumberTable,*Annotation*,EnclosingMethod
-keep public class com.banshee.** { public protected *; }
-keep public class org.xml.sax.EntityResolver { public protected *; }

请注意,在 Windows 中,您需要对 -injars 使用分号。可恶的。

构建器如下所示:

(running cygwin here, so the cat option path takes a slash)
James@Greine:/cygdrive/c/Users/james/workspace/Scala2$ cat .externalToolBuilders/proguard.launch
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="org.eclipse.ui.externaltools.ProgramBuilderLaunchConfigurationType">
<booleanAttribute key="org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND" value="false"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="C:\Windows\System32\java.exe"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS" value="full,incremental,auto,"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="-Xmx1g -jar lib/proguard.jar @proguard_windows.txt"/>
<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED" value="true"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${build_project}"/>
</launchConfiguration>

您需要将其放入 .externalToolBuilders/proguard.launch 中。

这里有趣的是,它只是一个 java 命令,而不是任何类型的 shell 脚本,因此在 Windows/Mac 之间移植相当容易(我假设是 Linux,但还没有这样做),因为你只是更改实际 java 二进制文件的位置。

(将此作为新答案提交,因为它与标记为正确答案的答案有点不同)

I'm now using a modification of my previous answer to run on Windows: just move everything into @proguard_windows.txt so you don't have to worry about running as a script.

My new @proguard_windows.txt looks like:

-injars bin;lib/scala-library.jar(!META-INF/MANIFEST.MF,!library.properties)

-outjar gen/scandroid.jar

-libraryjars lib/android.jar

-dontwarn
-dontoptimize
-dontobfuscate
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers

-keepattributes Exceptions,InnerClasses,Signature,Deprecated,
                SourceFile,LineNumberTable,*Annotation*,EnclosingMethod
-keep public class com.banshee.** { public protected *; }
-keep public class org.xml.sax.EntityResolver { public protected *; }

And note that in windows, you need to use a semicolon for -injars. Nasty.

The builder looks like this:

(running cygwin here, so the cat option path takes a slash)
James@Greine:/cygdrive/c/Users/james/workspace/Scala2$ cat .externalToolBuilders/proguard.launch
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="org.eclipse.ui.externaltools.ProgramBuilderLaunchConfigurationType">
<booleanAttribute key="org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND" value="false"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="C:\Windows\System32\java.exe"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS" value="full,incremental,auto,"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="-Xmx1g -jar lib/proguard.jar @proguard_windows.txt"/>
<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED" value="true"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${build_project}"/>
</launchConfiguration>

You'll want to put this in .externalToolBuilders/proguard.launch.

The interesting thing here is that it's just a java command, not any kind of shell script, so it's fairly easy to port between Windows/Mac (and I'm assuming Linux, but haven't done that yet), since you're just changing the location of the actual java binary.

(Submitting this as a new answer because it's a bit different than the one that got marked as the correct(ish) answer)

瘫痪情歌 2024-09-07 08:05:33

我一直在使用 Proguard 在 Eclipse/ADT 构建中对 Scala 库进行 Treeshake,但它还有很多不足之处。它很慢并且会弄乱其他 .class 文件,因此您必须经常重建项目。

受到这些问题和 Android 问题跟踪器中的一些问题的启发,我制作了另一个工具(基于 Jar Jar Links),现在我用它来对 scala 库进行 Treeshake。通过这个构建步骤,我实际上对 Android 上的整个 Eclipse+ADT Scala 情况相当满意。也许它也适合您,尝试一下,可以从 http://code.google 获取.com/p/treeshaker/

I have been using Proguard to treeshake the Scala library in Eclipse/ADT builds, but it leaves a lot to be desired. It's slow and it messes up the other .class files, so you have to rebuild the project more often than not.

Inspired by these questions and some of the issues in the Android issue tracker, I have made another tool (based on Jar Jar Links) which I now use to treeshake the scala library. With this build step I'm actually fairly happy with the whole Eclipse+ADT Scala on Android situation. Maybe it'll work for you too, give it a spin, it's available from http://code.google.com/p/treeshaker/

剩余の解释 2024-09-07 08:05:33

如果您习惯使用 Gradle 构建工具,那么 Gradle 的 Android 插件会让整个过程变得非常简单。请参阅: https://github.com/jvoegele/gradle-android-plugin/wiki< /a>

If you are comfortable using the Gradle build tool, then the Android plugin for Gradle makes this whole process extremely simple. See: https://github.com/jvoegele/gradle-android-plugin/wiki

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文