Jak stworzyć bibliotekę Androida z gradle bez publicznego ujawniania kodu źródłowego?
Chciałbym stworzyć Jar z projektu biblioteki Androida. Jest ona ustawiona w następujący sposób:
ProjectName
\- lib
| \- lib
| \- armeabi
| \- libNativeFirst.so
| \- libNativeSecond.so
\- src
\- main
\- java
\- com.package.sdk
\- PackageSDK.java
Chciałbym, aby wszystko to zostało zapakowane w słoik, ale bez ujawniania kodu źródłowego obecnego w PackageSDK.java
.
Ustawiłem mój build.gradle
plik tak:
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
}
Kiedy uruchamiam gradlew clean jar
w katalogu projektu, w ProjectName\build\libs
tworzony jest plik Jar o nazwie ProjectName.jar
. Jego struktura jest następująca:
ProjectName.jar
\- lib
| \- armeabi
| \- libNativeFirst.so
| \- libNativeSecond.so
\- com
\- package
\- sdk
\- PackageSDK.java
Chciałbym, aby skompilowany PackageSDK.class
został dołączony zamiast pliku PackageSDK.java
podczas wykonywania zadania jar
. Co mogę zmienić, aby to osiągnąć?
Edit:
Zgodnie z sugestią Bena Manesa zmieniłem konfigurację sourceSets
na następującą:
sourceSets {
main {
java {
srcDir 'src/main/java'
}
resources {
srcDir 'src/../lib'
}
output {
classesDir 'build/classes'
resourcesDir 'build/javaResources'
}
}
}
I jar
zadanie do:
task jar(type: Jar) {
from android.sourceSets.main.output
}
Gradle daje mi teraz to wyjście:
Could not find method output() for arguments [build_25r1m0a3etn5cudtt5odlegprd$_run_closure2_closure9_closure10_closure13@138532dc] on source set main.
2 answers
Uwaga: odpowiedź została edytowana. Zapoznaj się z aktualizacją 07/28/2014 poniżej.
Oto rozwiązanie, które wymyśliłem. Może jest lepszy sposób dostępny, ale jeszcze go nie znalazłem.
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
tworzy ProjectName.jar
w katalogu build/libs
. Struktura tego słoika jest następująca:
ProjectName.jar
\- lib
| \- armeabi
| \- libNativeFirst.so
| \- libNativeSecond.so
\- com
\- package
\- sdk
\- PackageSDK.class
To jest dokładny wynik, którego potrzebowałem. Jestem teraz w stanie z powodzeniem wykorzystać ProjectName.jar
w innych projektach.
EDIT: skoro jestem w stanie użyć wynikający jar w projektach w Android Studio, nie mogę tego zrobić w projektach utworzonych w ADT z powodu ostrzeżenia o kodzie natywnym obecnym wewnątrz pliku jar. Podobno jest flaga, aby wyłączyć to sprawdzenie w Ustawieniach, ale nie działa poprawnie. Tak więc, jeśli chcesz utworzyć bibliotekę, która używa kodu natywnego, osoby korzystające z ADT będą musiały ręcznie skopiować katalog armeabi do libs/.
07/28/2014 aktualizacja:
Od wersji Android Studio 0.8.0, katalogi wyjściowe Gradle zostały zmienione i konfiguracja opisana powyżej nie będzie działać. Zmieniłem konfigurację na:
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')
}
Ważne: należy pamiętać, że ProjectName.jar
będzie teraz umieszczony w build/outputs/
, a nie w build/libs/
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-29 18:26:50
Aby dodać lekką alternatywę dla odpowiedzi @BVB (choć mocno na niej bazującej) oto, co musiałem zrobić, aby wygenerować Jar myapp-api.jar
, który był tylko dla projektu Java, który zajmował się interakcją z rest API. Zależy od Androida.jar stąd potrzeba użycia apply plugin: 'com.android.application'
a nie tylko apply plugin: 'java'
Wywołanie ./gradlew build jar
z myJavaAPIProject w celu zbudowania i wygenerowania .jar to myJavaAPIProject/build/libs/myapp-api.jar
Zbuduj.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"
/>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-13 17:16:43