How to create an Android Library Jar with gradle without publicly revealing source code?

前端 未结 2 1490
无人共我
无人共我 2020-11-27 11:14

I would like to create a Jar out of an Android library project. It is set up the following way:

ProjectName
    \\- lib
    |   \\- lib
    |       \\- armea         


        
相关标签:
2条回答
  • 2020-11-27 11:54

    Just to add a slight alternative to @BVB's answer (although heavily based on it) here's what I had to do to output a jar myapp-api.jar which was for a Java only project that dealt with rest API interaction. It's dependant on Android.jar hence the need to use apply plugin: 'com.android.application' rather than just apply plugin: 'java'

    Calling ./gradlew build jar from the myJavaAPIProject to build and generate the .jar to 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"
        />
    
    0 讨论(0)
  • 2020-11-27 12:03

    Note: The answer has been edited. Please see the 07/28/2014 update below.

    Here is a solution I ended up coming up with. There may be a better way available, but I have not found it yet.

    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)
    

    Running gradlew makeJar creates a ProjectName.jar in the build/libs directory. The structure of this jar is as follows:

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

    This is the exact result I needed. I am now able to use ProjectName.jar successfully in other projects.

    EDIT: While I am able to use the resulting jar in projects within Android Studio, I cannot do so in projects created in ADT due to a warning about native code being present inside a jar file. Supposedly there is a flag to turn off this check in settings, but it does not function correctly. Thus, if you want to create a library that uses native code, those using ADT will have to manually copy the armeabi directory into libs/.

    07/28/2014 Update:

    As of Android Studio 0.8.0, Gradle output directories have been changed and the configuration outlined above will not work. I have changed my configuration to the following:

    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')
    }
    

    IMPORTANT: Please note that ProjectName.jar will now be placed into build/outputs/ and NOT into build/libs/.

    0 讨论(0)
提交回复
热议问题