【问题标题】:Android Ivy ActionBarSherlockAndroid Ivy ActionBarSherlock
【发布时间】:2012-11-21 21:29:12
【问题描述】:

是否可以将“apklib”类型用于 Ivy 依赖项?

在我的项目中,我使用的是 ActionBarSherlock 库,我想使用 Ivy 来检索依赖项。

这是我不工作的 xml:

<dependency
    name="actionbarsherlock"
    conf="binaries"
    org="com.actionbarsherlock"
    rev="4.2.0"
    transitive="true"
    type="apklib" />

感谢您的帮助!

【问题讨论】:

    标签: android dependencies actionbarsherlock ivy


    【解决方案1】:

    在这种情况下,只需要一个简单的依赖声明,如下所示:

    <dependency org="com.actionbarsherlock" name="actionbarsherlock" rev="4.2.0" conf="default"/>
    

    为什么?这个 Maven 模块很特别,Maven POM 已经配置了一个包装设置为值“apklib”。这意味着模块的主文件是“actionbarsherlock-4.2.0.apklib”,而不是默认的 .jar 文件。

    令人困惑的是还有一个jar文件发布了......要检索这个,您可以添加特殊的工件标签:

    <dependency org="com.actionbarsherlock" name="actionbarsherlock" rev="4.2.0" conf="default">
        <artifact name="actionbarsherlock" type="jar"/>
    </dependency>
    

    要查看此模块发布的所有文件,我推荐Maven search

    【讨论】:

    • 在 Eclipse 中是否可以与 ivyde 一起使用?据我所知,它不适用于 Eclipse 3.8 和 ivyde nightlies...
    • 罐子不够用。此外,常春藤获取 apklib 文件,但问题是你用它做什么..看我的回答。 :)
    • @aleb 是的,您的回答更全面。我的重点是关于“apklib”类型的问题(由于 Maven POM 文件的设置方式,不需要指定)。
    • @Nameiscarl 不明白为什么它在 Eclipse 中不起作用。仍然会利用常春藤功能。常春藤在 Eclipse 3.8 中工作吗?也许这个问题更笼统。 Eclipse IDE 是一个单独的项目。
    【解决方案2】:

    例如,您可以在 ivy.xml 中拥有:

      <configurations>
        <conf name="compiling"/>
      </configurations>
      <dependencies>
        <dependency org="com.actionbarsherlock" name="actionbarsherlock" rev="4.3.1" conf="compiling->master"/>
    

    如果你使用 ant,那么在 build.xml 中你可以有一个为你准备这些“apklib”文件的目标:

      <target name="ivy">
        <taskdef resource="org/apache/ivy/ant/antlib.xml" uri="antlib:org.apache.ivy.ant" classpath="ivy-2.3.0.jar"/>
        <ivy:retrieve conf="compiling" type="apklib" pattern="libs/[artifact].apklib"/>
        <!-- For each apklib artifact you need to unpack it so you can use it. -->
        <unzip src="libs/actionbarsherlock.apklib" dest="apklibs/action-bar-sherlock"/>
    

    现在你在 apklibs/action-bar-sherlock 中有库项目的 src/、res/ 等。

    这是一个完整的 build.xml 示例,说明如何构建依赖于多个 Android 库项目的 Android 应用的 APK:

    <?xml version="1.0" encoding="utf-8"?>
    
    <project name="dev" default="release" xmlns:ivy="antlib:org.apache.ivy.ant">
    
      <!-- According to http://developer.android.com/sdk/requirements.html -->
      <property name="ant.build.javac.source" value="1.6"/>
      <property name="ant.build.javac.target" value="1.6"/>
    
      <property file="local.properties"/>
      <property file="project.properties" prefix="android.project"/>
    
      <property name="android.target.dir" value="${sdk.dir}/platforms/${android.project.target}"/>
      <property name="android.jar" value="${android.target.dir}/android.jar"/>
      <property name="apk.name" value="YOUR_APP.apk"/>
      <property name="out.dir" value="build/compiled"/>
      <property name="out.test-classes.dir" value="build/compiled-test"/>
      <property name="test.libs.dir" value="libs/test"/>
    
      <target name="clean">
        <delete dir="build"/>
        <delete dir="gen"/>
        <delete dir="apklibs"/>
        <delete file="${apk.name}"/>
      </target>
    
      <target name="ivy">
        <taskdef resource="org/apache/ivy/ant/antlib.xml" uri="antlib:org.apache.ivy.ant" classpath="ivy-2.3.0.jar"/>
        <ivy:retrieve conf="compiling" type="bundle,jar" pattern="libs/[artifact].[ext]"/>
        <ivy:retrieve conf="compiling" type="apklib" pattern="libs/[artifact].apklib"/>
        <unzip src="libs/actionbarsherlock.apklib" dest="apklibs/action-bar-sherlock"/>
        <unzip src="libs/library.apklib" dest="apklibs/view-pager-indicator"/>
        <path id="lib.path.id">
          <fileset dir="libs" includes="*.jar"/>
        </path>
        <ivy:retrieve conf="compiling" type="source" pattern="sources/[artifact].[ext]" sync="true"/>
        <ivy:retrieve conf="packaging" type="bundle,jar" pattern="[artifact]-[revision].[ext]"/>
        <ivy:retrieve conf="testing" type="bundle,jar" pattern="libs/test/[artifact].[ext]"/>
      </target>
    
      <target name="-check-properties" unless="sdk.dir">
        <echo>
          You need to create a local.properties file with:
          storepass=...the password...
          sdk.dir=...path to Android SDK...
        </echo>
      </target>
    
      <target name="generate" depends="-check-properties">
        <mkdir dir="gen"/>
        <mkdir dir="build"/>
        <condition property="debug.mode" value="--debug-mode" else="">
          <istrue value="${debug}"/>
        </condition>
        <echo>debug=${debug}</echo>
        <echo>debug.mode=${debug.mode}</echo>
        <exec executable="${sdk.dir}/platform-tools/aapt" failonerror="true">
          <arg value="package"/>
          <arg line="${debug.mode}"/>
          <arg value="-f"/>
          <arg value="-m"/>
          <arg value="--auto-add-overlay"/>
          <arg value="-M"/>
          <arg file="AndroidManifest.xml"/>
          <arg value="-F"/>
          <arg file="build/resources.arsc"/>
          <arg value="-I"/>
          <arg file="${android.jar}"/>
          <arg value="-J"/>
          <arg file="gen"/>
          <arg value="-S"/>
          <arg file="facebook-android-sdk/facebook/res"/>
          <arg value="-S"/>
          <arg file="apklibs/view-pager-indicator/res"/>
          <arg value="-S"/>
          <arg file="barone/res"/>
          <arg value="-S"/>
          <arg file="apklibs/action-bar-sherlock/res"/>
          <arg value="-S"/>
          <arg file="res"/>
          <arg value="--extra-packages"/>
          <arg value="com.facebook.android:com.viewpagerindicator:com.triposo.barone:com.actionbarsherlock"/>
          <arg value="-A"/>
          <arg file="assets"/>
        </exec>
        <taskdef name="buildconfig" classname="com.android.ant.BuildConfigTask"
                 classpath="${sdk.dir}/tools/lib/anttasks.jar"/>
        <buildconfig
            genFolder="gen"
            package="com.actionbarsherlock"
            buildType="${debug}"
            previousBuildType=""/>
        <buildconfig
            genFolder="gen"
            package="COM.YOUR.PACKAGE"
            buildType="${debug}"
            previousBuildType=""/>
      </target>
    
      <target name="compile" depends="clean, ivy, generate">
        <mkdir dir="${out.dir}"/>
        <javac destdir="${out.dir}" debug="true" includeantruntime="false">
          <src path="src"/>
          <src path="facebook-android-sdk/facebook/src"/>
          <src path="apklibs/view-pager-indicator/src"/>
          <src path="barone/src"/>
          <src path="apklibs/action-bar-sherlock/src"/>
          <src path="gen"/>
          <classpath>
            <path refid="lib.path.id"/>
            <pathelement path="${android.jar}"/>
          </classpath>
        </javac>
        <copy todir="${out.dir}">
          <fileset dir="src" excludes="**/*.java"/>
          <fileset dir="gen" excludes="**/*.java"/>
        </copy>
      </target>
    
      <target name="apk-unsigned" depends="compile">
        <!-- Prepare the .class files and the .properties files. -->
        <taskdef name="jarjar" classname="com.tonicsystems.jarjar.JarJarTask"
                 classpath="jarjar-1.1.jar"/>
        <jarjar jarfile="build/app.jar" duplicate="preserve">
          <fileset dir="${out.dir}"/>
          <zipgroupfileset dir="libs" includes="*.jar"/>
          <keep pattern="COM.YOUR.PACKAGE.**"/>
          <keep pattern="com.amazonaws.**"/>
          <keep pattern="com.facebook.android.**"/>
          <keep pattern="com.google.android.apps.analytics.**"/>
          <keep pattern="com.google.gson.GsonBuilder"/>
          <keep pattern="com.google.common.base.Splitter"/>
          <keep pattern="com.google.common.io.Files"/>
          <keep pattern="com.google.common.base.Charsets"/>
          <keep pattern="javax.annotation.Nullable"/>
          <keep pattern="org.apache.commons.lang3.**"/>
          <keep pattern="android.support.v4.**"/>
          <!-- Required because these seem to be missing from the phone JVM
               and they are used by our CursorMapper. -->
          <keep pattern="javax.annotation.**"/>
          <!-- From http://actionbarsherlock.com/faq.html -->
          <keep pattern="com.actionbarsherlock.**"/>
          <keep pattern="*Annotation*"/>
          <rule pattern="com.google.common.**" result="COM.YOUR.PACKAGE.vendor.com.google.common.@1"/>
          <!-- We rename this because at least "HTC Sensation XL with Beats Audio"
               has a bad Gson library which we don't want to use. -->
          <rule pattern="com.google.gson.**" result="COM.YOUR.PACKAGE.vendor.com.google.gson.@1"/>
        </jarjar>
        <!-- Convert the .class files to Dalvik byte code. -->
        <exec executable="${sdk.dir}/platform-tools/dx" failonerror="true">
          <arg value="--dex"/>
          <arg value="--output=build/classes.dex"/>
          <arg file="build/app.jar"/>
        </exec>
        <!-- Package the resources and the classes into an apk. -->
        <taskdef name="apkbuilder" classname="com.android.ant.ApkBuilderTask"
                 classpath="${sdk.dir}/tools/lib/anttasks.jar"/>
        <apkbuilder outfolder="."
                    resourcefile="build/resources.arsc"
                    apkfilepath="build/unsigned.apk"
                    verbose="false">
          <dex path="build/classes.dex"/>
          <sourcefolder path="${out.dir}"/>
        </apkbuilder>
      </target>
    
      <!-- We need this because I use JDK 7, see the Caution in:
           http://developer.android.com/guide/publishing/app-signing.html#signapp
           Ant 1.8.3 allows specifying a sigalg and a digestalg, but
           I don't have it yet, so we have this macro instead. -->
      <macrodef name="signjarjdk7">
        <attribute name="jar" />
        <attribute name="signedjar" />
        <attribute name="keystore" />
        <attribute name="storepass" />
        <attribute name="alias" />
        <sequential>
          <exec executable="jarsigner" failonerror="true">
            <arg line="-digestalg SHA1 -sigalg MD5withRSA" />
            <arg line="-keystore @{keystore} -storepass @{storepass}" />
            <arg line="-signedjar &quot;@{signedjar}&quot;" />
            <arg line="&quot;@{jar}&quot; @{alias}" />
          </exec>
        </sequential>
      </macrodef>
    
      <macrodef name="zipalign">
        <attribute name="apk" />
        <attribute name="optimizedapk" />
        <sequential>
          <exec executable="${sdk.dir}/tools/zipalign" failonerror="true">
            <arg value="-f"/>
            <arg value="4"/>
            <arg file="@{apk}"/>
            <arg file="@{optimizedapk}"/>
          </exec>
        </sequential>
      </macrodef>
    
      <!-- Make an apk.
           See http://developer.android.com/guide/developing/building/index.html -->
      <macrodef name="apk">
        <attribute name="keystore"/>
        <attribute name="storepass"/>
        <attribute name="alias"/>
        <sequential>
          <antcall target="apk-unsigned"/>
          <!-- Sign the apk for release. -->
          <signjarjdk7
              keystore="@{keystore}" storepass="@{storepass}" alias="@{alias}"
              jar="build/unsigned.apk" signedjar="build/unaligned.apk"/>
          <!-- Optimize the apk to improve speed. -->
          <zipalign apk="build/unaligned.apk" optimizedapk="${apk.name}"/>
        </sequential>
      </macrodef>
    
      <target name="release">
        <property name="debug" value="false"/>
        <apk keystore="keystore" storepass="${storepass}" alias="YOUR ALIAS"/>
      </target>
    
      <target name="debug">
        <property name="debug" value="true"/>
        <apk keystore="debug.keystore" storepass="android" alias="androiddebugkey"/>
      </target>
    
      <target name="compile.tests" depends="compile">
        <mkdir dir="${out.test-classes.dir}"/>
    
        <javac encoding="ascii" source="1.6" target="1.6" debug="true" extdirs=""
               includeantruntime="false"
               destdir="${out.test-classes.dir}">
          <src path="test"/>
          <classpath>
            <pathelement path="${out.dir}"/>
            <path refid="lib.path.id"/>
            <fileset dir="${test.libs.dir}" includes="*.jar"/>
            <pathelement path="${android.jar}"/>
          </classpath>
        </javac>
      </target>
    
      <target name="test" depends="compile.tests">
        <mkdir dir="${basedir}/out/reports/tests"/>
        <junit showoutput="true" failureproperty="junit.failure">
          <formatter type="plain" usefile="false"/>
          <formatter type="xml"/>
          <batchtest todir="${basedir}/out/reports/tests">
            <fileset dir="test">
              <include name="**/*Test.java"/>
            </fileset>
          </batchtest>
          <classpath>
            <pathelement path="${out.dir}"/>
            <path refid="lib.path.id"/>
            <fileset dir="${test.libs.dir}" includes="*.jar"/>
            <pathelement path="${android.jar}"/>
            <pathelement path="${out.test-classes.dir}"/>
          </classpath>
        </junit>
        <fail if="junit.failure" message="Unit test(s) failed.  See reports!"/>
      </target>
    </project>
    

    【讨论】:

    • ivy taskdef 是可选的,前提是 ivy jar 位于 $ANT_HOME/lib 或 $HOME/.ant/lib(安装 ANT 扩展的标准位置)。为什么? ivy 被打包为 antlib。
    • 这个想法是 git 克隆一个项目并能够立即构建它,每个人都使用相同的工具(常春藤库)。现在使用新的 gradle 构建系统已经过时了..
    • Gradle 非常非常酷。不幸的是,我还没有看到它从 Maven 和 ANT 手中接管......
    猜你喜欢
    • 1970-01-01
    • 2013-08-16
    • 2012-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多