How to Create an Android Library Jar with Gradle Without Publicly Revealing Source Code

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

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

Generating jar files using progaurd in gradle android build

My requirement of generating individual obfuscated jar files based on few selected class files from single library project is achieved with below way. These individual jar files are in addition to final android binary i.e, .aar file.

Debug :
1. During android build, gradle moves all the compiled java files to /build/intermediates/javac/debug/compileDebugJavaWithJavac/classes folder.


  1. In proguard file I have given -injars as above folder and -outjars as my custom path with filters.

  2. Using 'proguardFile' attribute I have passed proguard file to build.gradle

  3. All the individual jar files specified using -injars and -outjars would be obfuscated and will be placed in -outjars path

Eg :

In debug mode :

-injars 'D:\projectname\build\intermediates\javac\debug\compileDebugJavaWithJavac\classes'(**.class)

-outjars 'D:\projectname\build\intermediates\transforms\proguard\debug\1.jar'(com/ui/tab/TabWidget.class,com/ui/Tab.class)

-injars 'D:\projectname\build\intermediates\javac\debug\compileDebugJavaWithJavac\classes'(**.class)

-outjars 'D:\projectname\build\intermediates\transforms\proguard\debug\1.jar'(com/ui/CollapsibleWidget.class)

Android Gradle Build System: Create Jar Not Library

With newer versions of gradle and the android gradle plugin, you just need to add the following to your build.gradle:

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

and run gradle clean compileReleaseJava jar

On older versions of the gradle plugin, your sourceSets element needs be inside android:

android {
compileSdkVersion 17
buildToolsVersion "17.0.0"

defaultConfig {
minSdkVersion 7
targetSdkVersion 16
}

sourceSets {
main {
java {
srcDir 'src/main/java'
}
}
}
}

Then, your jar task would need to reference android.sourceSets:

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

Application works if library is connected to source, but not from jar created from that source

I found an issue:

In my library I have dependency:

compile 'com.google.android.gms:play-services:8.4.0'

And don't have it on my demo project.

And it hungs on this lines, inside library:

    Info adInfo = AdvertisingIdClient.getAdvertisingIdInfo(mContext);

The solution is to add dependency on demo also, use some other method to get Google Advertising id.

How to export library to Jar in Android Studio?

It is not possible to export an Android library as a jar file. It is possible, however, to export it as aar file. Aar files being the new binary format for Android libraries. There's info about them in Google I/O, the New Build System video.

First, build the library in Android Studio or from command line issuing gradle build from your library's root directory.

This will result in <yourlibroot>/libs/build/yourlib.aar file.

This aar file is a binary representation of your library and can be added to your project instead of the library as a dependency project.

To add aar file as a dependency you have to publish it to the maven central or to your local maven repository, and then refer the aar file in your project's gradle.build file.

However, this step is a bit convoluted. I've found a good explanation how to do so here:

http://www.flexlabs.org/2013/06/using-local-aar-android-library-packages-in-gradle-builds

Generate a single .jar with only androidTest code

There is a special gradle task to run tests on connected device or emulator

gradle :module_name:connectedCheck

Test results will be available in ./build/outputs/androidTest-results folder.

But if you want to do it in two separate steps (assemble apk & run it via adb shell), use this command to assemble the apk with tests

gradle :module_name:assembleAndroidTest

Find out the .apk file in ./build/outputs/apk folder of your module.
Let install it with command

gradle :module_name:installDebugAndroidTest

or

adb install ./module_name/build/outputs/apk/module_name-debug-androidTest-unaligned.apk

Now start the tests

adb shell am instrument -w -e package <package_with_tests> <package_from_manifest>/android.test.InstrumentationTestRunner

The results appear in STDOUT.



Related Topics



Leave a reply



Submit