android - 如何在不公开源代码的情况下使用 gradle 创建 Android Library Jar?

标签 android jar gradle android-studio android-gradle-plugin

我想从一个 Android 库项目中创建一个 Jar。设置方式如下:

ProjectName
    \- lib
    |   \- lib
    |       \- armeabi
    |           \- libNativeFirst.so
    |           \- libNativeSecond.so
    \- src
        \- main
            \- java
                \- com.package.sdk
                    \- PackageSDK.java

我希望将所有这些打包在一个 Jar 中,但不透露 PackageSDK.java 中的源代码。

我像这样设置我的 build.gradle 文件:

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.5.+'
    }
}

apply plugin: 'android-library'

repositories {
    mavenCentral()
}

android {
    compileSdkVersion 18
    buildToolsVersion "18.0.1"

    defaultConfig {
        minSdkVersion 10
        targetSdkVersion 18
    }

    sourceSets {
        main {
            java {
                srcDir 'src/main/java'
            }
            resources {
                srcDir 'src/../lib'
            }
        }
    }
}

task jar(type: Jar) {
    from android.sourceSets.main.allSource
}

当我在项目目录中运行 gradlew clean jar 时,会在 ProjectName\build\libs 中创建一个名为 ProjectName.jar 的 Jar 文件.其结构如下:

ProjectName.jar
    \- lib
    |   \- armeabi
    |       \- libNativeFirst.so
    |       \- libNativeSecond.so
    \- com
        \- package
            \- sdk
                \- PackageSDK.java

我希望在执行 jar 任务时包含已编译的 PackageSDK.class 而不是 PackageSDK.java 文件。我可以改变什么来实现这一点?

编辑:

根据 Ben Manes 的建议,我将 sourceSets 的配置更改为以下内容:

sourceSets {
    main {
        java {
            srcDir 'src/main/java'
        }
        resources {
            srcDir 'src/../lib'
        }
        output {
            classesDir 'build/classes'
            resourcesDir 'build/javaResources'
        }
    }
}

jar任务如下:

task jar(type: Jar) {
    from android.sourceSets.main.output
}

Gradle 现在给我这个输出:

在源集 main 上找不到参数 [build_25r1m0a3etn5cudtt5odlegprd$_run_closure2_closure9_closure10_closure13@138532dc] 的方法 output()。

最佳答案

注意:答案已被编辑。请参阅下面的 2014 年 7 月 28 日更新。

这是我最终想出的解决方案。可能有更好的方法可用,但我还没有找到。

android {
    compileSdkVersion 18
    buildToolsVersion "18.0.1"

    defaultConfig {
        minSdkVersion 10
        targetSdkVersion 18
    }

    sourceSets {
        main {
            java {
                srcDir 'src/main/java'
            }
            resources {
                srcDir 'src/../lib'
            }
        }
    }
}

task clearJar(type: Delete) {
    delete 'build/libs/ProjectName.jar'
}

task makeJar(type: Copy) {
    from('build/bundles/release/')
    into('build/libs/')
    include('classes.jar')
    rename ('classes.jar', 'ProjectName.jar')
}

makeJar.dependsOn(clearJar, build)

运行 gradlew makeJarbuild/libs 目录中创建一个 ProjectName.jar。这个jar的结构如下:

ProjectName.jar
    \- lib
    |   \- armeabi
    |       \- libNativeFirst.so
    |       \- libNativeSecond.so
    \- com
        \- package
            \- sdk
                \- PackageSDK.class

这正是我需要的结果。我现在可以在其他项目中成功使用 ProjectName.jar

编辑:虽然我可以在 Android Studio 中的项目中使用生成的 jar,但我不能在 ADT 中创建的项目中这样做,因为有关 jar 文件中存在 native 代码的警告。据说有一个标志可以关闭此 checkin 设置,但它无法正常工作。因此,如果你想创建一个使用原生代码的库,那些使用 ADT 的人将不得不手动将 armeabi 目录复制到 libs/中。

2014 年 7 月 28 日更新:

从 Android Studio 0.8.0 开始,Gradle 输出目录已更改,上述配置将不起作用。我已将配置更改为以下内容:

task clearJar(type: Delete) {
    delete 'build/outputs/ProjectName.jar'
}

task makeJar(type: Copy) {
    from('build/intermediates/bundles/release/')
    into('build/outputs/')
    include('classes.jar')
    rename ('classes.jar', 'ProjectName.jar')
}

重要提示:请注意,ProjectName.jar 现在将被放入 build/outputs/ 而不是 build/libs/.

关于android - 如何在不公开源代码的情况下使用 gradle 创建 Android Library Jar?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19034466/

相关文章:

java - 如何将xml文件传递给Jmeter中的新对象

android - 错误 :Lambda coming from jar file need their interfaces on the classpath to be compiled, 未知接口(interface)是 java.util.function.Function

java - 无法打开数据库,因为数据库不存在

java - 我的 php 代码连接到 android 数据库

java - 如何使用 eclipse 将类路径添加到导出的可运行 java .jar 文件

java - 圆形 jar 引用 - 它可以编译吗?

gradle - 这两行之间的差异..

gradle - 有没有一种方法可以 “merge” gradle任务来避免许多dependsOn声明

java - ActiveAndroid TypeSerializer - 枚举列表

android - 应用程序以原生 4k 显示其图像内容的机制