如何在没有公开披露源代码的情况下使用gradle创建Android库Jar?

时间:2013-09-26 17:13:29

标签: android jar gradle android-studio android-gradle

我想从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的{​​{1}}中创建一个Jar文件。它的结构如下:

ProjectName.jar

我希望在执行ProjectName.jar \- lib | \- armeabi | \- libNativeFirst.so | \- libNativeSecond.so \- com \- package \- sdk \- PackageSDK.java 任务时包含已编译的PackageSDK.class而不是PackageSDK.java文件。我可以改变什么来实现这个目标?

编辑:

Per Ben Manes的建议,我将jar的配置更改为以下内容:

sourceSets

以下sourceSets { main { java { srcDir 'src/main/java' } resources { srcDir 'src/../lib' } output { classesDir 'build/classes' resourcesDir 'build/javaResources' } } } 任务:

jar

Gradle现在给我这个输出:

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

2 个答案:

答案 0 :(得分:69)

注意:答案已被修改。请参阅下面的07/28/2014更新。

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

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 makeJar会在ProjectName.jar目录中创建build/libs。这个罐子的结构如下:

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

这是我需要的确切结果。我现在能够在其他项目中成功使用ProjectName.jar

编辑:虽然我能够在Android Studio中的项目中使用生成的jar,但由于有关jar文件中存在本机代码的警告,我无法在ADT中创建的项目中执行此操作。据说有一个标志可以关闭此检查设置,但它无法正常工作。因此,如果要创建使用本机代码的库,则使用ADT的库必须手动将armeabi目录复制到libs /中。

07/28/2014更新:

自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/

答案 1 :(得分:8)

只是为@BVB的答案添加了一个小的替代方案(虽然很大程度上基于它),这是我必须要输出的jar myapp-api.jar,这是一个仅用于处理其余API交互的Java项目。它取决于Android.jar因此需要使用apply plugin: 'com.android.application'而不仅仅是apply plugin: 'java'

从myJavaAPIProject调用./gradlew build jar来构建并生成.jar到myJavaAPIProject/build/libs/myapp-api.jar

的build.gradle

//Even though this is a Java project, we need to apply the android plugin otherwise it cannot find the SDK/android.jar and so cannot compile
apply plugin: 'com.android.application'

dependencies {
    //this ensures we have gson.jar and anything else in the /lib folder
    compile fileTree(dir: 'lib', include: '*.jar')
}

repositories {
    mavenCentral()
}
android{
    compileSdkVersion 21
    buildToolsVersion "21.0.1"

    defaultConfig {
        minSdkVersion 10
        targetSdkVersion 21
    }

    sourceSets {
        main {
            java {
                //points to an empty manifest, needed just to get the build to work
                manifest.srcFile 'AndroidManifest.xml'
                //defined our src dir as it's not the default dir gradle looks for
                java.srcDirs = ['src']

            }
        }
    }

    //enforce java 7
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_7
        targetCompatibility JavaVersion.VERSION_1_7
    }
}

//Actually created the .jar file
task jar(type: Jar) {
    //from android.sourceSets.main.java
    from 'build/intermediates/classes/release/'
    archiveName 'myapp-api.jar'
}

的AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- this is a dummy file needed to ensure gradle validates and builds ok -->
<manifest
    package="com.myapp.android"
    />