代码之家  ›  专栏  ›  技术社区  ›  Kevin Wright

使用scala 2.8主干构建以Android为目标

  •  14
  • Kevin Wright  · 技术社区  · 16 年前

    在Android上使用scala的最终参考资料如下: http://www.scala-lang.org/node/160

    不幸的是,所有使用scala和android的参考都是基于scala 2.7,并引用了一个定制的构建android-library.jar,其中有一些神秘的参考表明这个定制的构建对于android的更高版本是不需要的(我使用的是2.1/api v7)。

    所以…在Android项目中使用scala 2.8需要哪些步骤?最好使用Eclipse和谷歌为该IDE提供的Android工具。

    5 回复  |  直到 14 年前
        1
  •  11
  •   James Moore    14 年前

    编辑:

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

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

    [旧方式] 我的方法是:

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

    不过,我并没有用这个来表示比你好更雄心勃勃的事情,所以把它当作一系列提示。

    在scala项目中,我添加了一个builder(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}
    

    另外,在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/ProGuord.jar)。

    不过,不要将Scala项目作为Java项目的构建路径中需要的项目添加。这将在jar文件之外添加scala类文件,并混淆dex(因为它将同时获得.class文件和jar中的相同内容)。据我所知,Eclipse将在工作区中构建所有东西,所以当您点击Go按钮时,两个项目都将被构建。

        2
  •  3
  •   Kevin Wright    16 年前

    经过大量的调查,Proguard看起来确实是将应用程序的部署规模和速度保持在合理水平的关键。

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

    我也不确定Twin项目解决方案,因为它阻止了scala代码使用生成的资源文件r.java,我希望能够这样做。

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

    然后Eclipse将Ant作为一个外部工具来打包和安装应用程序。

        3
  •  2
  •   James Moore    16 年前

    我现在正在修改以前的答案,以便在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二进制的位置。

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

        4
  •  0
  •   Carsten    15 年前

    我一直在使用Proguard在Eclipse/ADT构建中对scala库进行树化,但是它留下了很多需要的地方。它很慢,而且会把其他.class文件弄乱,因此您必须经常重新构建项目。

    受这些问题和Android问题追踪器中的一些问题的启发,我制作了另一个工具(基于jar-jar链接),我现在使用它来重新构建scala库。通过这个构建步骤,我对整个Eclipse+ADTScala在Android环境下的表现相当满意。也许对你也有用,转一圈,可以从 http://code.google.com/p/treeshaker/

        5
  •  -1
  •   Jason Voegele    16 年前

    如果您愿意使用Gradle构建工具,那么Gradle的Android插件使整个过程非常简单。见: http://wiki.github.com/jvoegele/gradle-android-plugin/