web-dev-qa-db-ja.com

ソースコードを公開せずにgradleでAndroid Library Jarを作成する方法は?

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は今、この出力を私に与えています:

Could not find method output() for arguments [build_25r1m0a3etn5cudtt5odlegprd$_run_closure2_closure9_closure10_closure13@138532dc] on source set main.

35
BVB

注:回答が編集されました。以下の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 makeJarを実行すると、ProjectName.jarディレクトリにbuild/libsが作成されます。このjarの構造は次のとおりです。

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

これは私が必要とした正確な結果です。他のプロジェクトでProjectName.jarを正常に使用できるようになりました。

編集:結果のjarをAndroid Studio内のプロジェクトで使用できますが、jarファイル内にネイティブコードが存在するという警告のためにADTで作成されたプロジェクトでは使用できません。設定でこのチェックをオフにするフラグがありますが、正しく機能しません。したがって、ネイティブコードを使用するライブラリを作成する場合、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.jarbuild/outputs/ではなくbuild/libs/に配置されることに注意してください。

69
BVB

@BVBの答えにわずかに代替を追加するために(それに大きく基づいていますが)、Javaのみが処理されたプロジェクト用のjar myapp-api.jar残りのAPIインタラクションを使用します。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"
    />
8
scottyab