Jak zbudować bibliotekę Androida za pomocą Android Studio i Gradle?

144

Próbuję migrować projekt z Eclipse, ale nic, co próbowałem, nie działa. W Eclipse mam 3 projekty (2 projekty aplikacji na Androida i 1 projekt biblioteki dla Androida). Te 2 projekty aplikacji zależą od projektu biblioteki. Kiedy wykonuję eksport Gradle, otrzymuję 3 projekty, które nie działają. Jestem otwarty na restrukturyzację projektu, ale nie znalazłem żadnej dokumentacji, jak to zrobić.

Czy istnieje sposób, aby 3 projekty eksportowane przez Eclipse współpracowały ze sobą? Czy lepiej będzie dla mnie restrukturyzacja, a jeśli tak, to czy dokumentacja, jak to zrobić?

Aktualizacja

Wgrałem cały projekt do GitHub https://github.com/respectTheCode/android-studio-library-example

Zaktualizuj 1

Opierając się na sugestiach Padmy Kumara, próbowałem tego.

  1. Utwórz nowy projekt o nazwie MyApp
  2. Kliknij File > New Module, wybierz Android Libraryi nazwijMyLib
  3. Kliknij Build > Make Project

Kompilacja kończy się niepowodzeniem z powodu tego błędu

Module "MyLib" was fully rebuilt due to project configuration/dependencies changes
Compilation completed with 1 error and 0 warnings in 19 sec
1 error
0 warnings
/.../MyApp/MyLib/build/bundles/debug/AndroidManifest.xml
Gradle: <manifest> does not have package attribute.

Następnie dodałem packageatrybut do manifestu, który go tworzy

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.mylib" >

Po zbudowaniu pojawia się ten błąd

Module "MyApp" was fully rebuilt due to project configuration/dependencies changes
Compilation completed with 2 errors and 0 warnings in 13 sec
2 errors
0 warnings
/.../MyApp/MyLib/src/main/java/com/example/mylib/MainActivity.java
Gradle: package R does not exist
Gradle: package R does not exist

Wydaje się, że dodanie zależności nie ma żadnego wpływu na błąd. Kontynuując z góry

  1. Kliknij File > Project Structure > Modules > MyApp-MyApp
  2. Przejdź do Dependencieskarty
  3. Kliknij + > Module Dependencyi wybierzMyLib
  4. Kliknij ApplyiOK
  5. Kliknij Build > Make Project

Zaktualizuj 2

Na podstawie sugestii Ethana otrzymujemy to

Wydaje się, że 2 podprojekty build.gradlemają wszystkie poprawne części, a jedyną różnicą jest to, że linia wtyczki poniżej to MyApp/build.gradle.

buildscript {
    repositories {
        maven { url 'http://repo1.maven.org/maven2' }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.4'
    }
}
apply plugin: 'android'

dependencies {
    compile files('libs/android-support-v4.jar')
}

android {
    compileSdkVersion 17
    buildToolsVersion "17.0.0"

    defaultConfig {
        minSdkVersion 7
        targetSdkVersion 16
    }
}

Projekt główny build.gradlebył pusty, więc dodałem dwa takie projekty

dependencies {
    compile project(":MyLib")
    compile project(":MyApp")
}

Teraz pojawia się ten błąd podczas budowania

Gradle:
FAILURE: Build failed with an exception.
* Where:
Build file '/Users/kevin/GitHub/AppPress/MyApp/build.gradle' line: 2
* What went wrong:
A problem occurred evaluating root project 'MyApp'.
> Could not find method compile() for arguments [project ':MyLib'] on root project 'MyApp'.
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

Zaktualizuj 3

Wielkie dzięki Ethan za rozwiązanie tego problemu.

  1. Dodaj compile project(':SubProjects:MyLib')doMyLib/build.gradle
  2. Usuń compile files('libs/android-support-v4.jar')zMyLib/build.gradle
  3. Zamknij projekt i zaimportuj główny projekt z Gradle

Zaktualizuj 4

Od wersji 0.1.2 możesz teraz uwzględniać compile "com.android.support:support-v4:13.0.0"zamiast compile files('libs/android-support-v4.jar'). Ponieważ teraz pochodzi z mavin, możesz bez problemu uwzględnić to w wielu projektach.

buildscript {
    repositories {
        mavenCentral()
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:0.4.2'
    }
}

apply plugin: 'android'

dependencies {
    compile "com.android.support:support-v4:13.0.0"

    compile project(':SubProjects:MyLib')
}

Zaktualizuj 5

Od wersji 0.1.3 na pasku narzędzi znajduje się przycisk „Synchronizuj projekt”. Możesz to kliknąć, zamiast ponownie importować projekt po wprowadzeniu zmian w .gradleplikach.

szacunekTheCode
źródło
Wysłałem prośbę o ściągnięcie dla twojego projektu na githubie. Były 2 proste zmiany. Usuń zawartość z /build.gradle. {Zrobiłem to, ponieważ nie zdefiniowałeś, jaki to był rodzaj projektu, więc narzekał, że nie wie, co z nim zrobić}, następnie dodałem zależność z: SubProject: MyLib do: SubProject: MyApp. Następnie uruchomiłem ./gradlew: SubProject: MyApp: iD (mapy iD do installDebug). Musiałem również usunąć zduplikowane libs / android-support-v4.jar. Ponieważ nie jest to „prawdziwa” zależność, nie możesz jej mieć w dwóch miejscach.
Ethan
Skomentowałem żądanie pull. github.com/respectTheCode/android-studio-library-example/pull/1
szacunekTheCode
1
Warto wspomnieć, że jeśli dodasz compile 'com.google.android:support-v4:r6'do każdego swojego projektu wtyczkę maven (jak w przykładzie build.gradle poniżej) zamiast compile files('libs/android-support-v4.jar')gradle, zdasz sobie sprawę, że oba projekty zawierają to samo i uwzględnią to tylko raz.
Ethan
@respectTheCode Wysłałem żądanie ściągnięcia, aby trochę wyczyścić twój przykładowy projekt na githubie. Dzięki za udostępnienie!
JohnnyLambada,
Możliwy duplikat Android Studio, Gradle i NDK
Cameron Lowell Palmer

Odpowiedzi:

115

Uwaga : ta odpowiedź jest czystą odpowiedzią Gradle, używam jej regularnie w IntelliJ, ale nie wiem, jak wygląda integracja z Android Studio. Wierzę, że wiem, co się ze mną dzieje, więc tak używam Gradle i Androida.

TL; DR Pełny przykład - https://github.com/ethankhall/driving-time-tracker/

Zastrzeżenie : jest to projekt, nad którym pracuję / nad którym pracowałem.

Gradle ma zdefiniowaną strukturę (którą możesz zmienić, link na dole mówi ci, jak), która jest bardzo podobna do Maven, jeśli kiedykolwiek z niej korzystałeś.

Project Root
+-- src
|   +-- main (your project)
|   |   +-- java (where your java code goes)
|   |   +-- res  (where your res go)
|   |   +-- assets (where your assets go)
|   |   \-- AndroidManifest.xml
|   \-- instrumentTest (test project)
|       \-- java (where your java code goes)
+-- build.gradle
\-- settings.gradle

Jeśli masz tylko jeden projekt, plik settings.gradle nie jest potrzebny. Jednak chcesz dodać więcej projektów, więc potrzebujemy tego.

Rzućmy teraz okiem na ten plik build.gradle. Będziesz tego potrzebował (aby dodać narzędzia Android)

build.gradle

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.3'
    }
}

Teraz musimy powiedzieć Gradle o niektórych częściach Androida. To całkiem proste. Podstawowy (który działa w większości moich przypadków) wygląda następująco. Mam komentarz w tym bloku, pozwoli mi to określić nazwę wersji i kod podczas generowania APK.

build.gradle

apply plugin: "android"
android {
        compileSdkVersion 17
        /*
        defaultConfig {
            versionCode = 1
            versionName = "0.0.0"
        }
        */
    }

Coś, co będziemy chcieli dodać, aby pomóc każdemu, kto jeszcze nie widział światła Gradle, aby mogli korzystać z projektu bez instalowania go.

build.gradle

task wrapper(type: org.gradle.api.tasks.wrapper.Wrapper) {
    gradleVersion = '1.4'
}

Więc teraz mamy jeden projekt do zbudowania. Teraz dodamy pozostałe. Umieściłem je w katalogu, może nazywam to deps lub subProjects. To naprawdę nie ma znaczenia, ale musisz wiedzieć, gdzie go położyłeś. Aby poinformować Gradle, gdzie są projekty, należy dodać je do pliku settings.gradle.

Struktura katalogów:

Project Root
+-- src (see above)
+-- subProjects (where projects are held)
|   +-- reallyCoolProject1 (your first included project)
|       \-- See project structure for a normal app
|   \-- reallyCoolProject2 (your second included project)
|       \-- See project structure for a normal app
+-- build.gradle
\-- settings.gradle

settings.gradle:

include ':subProjects:reallyCoolProject1'
include ':subProjects:reallyCoolProject2'

Ostatnią rzeczą, o którą powinieneś się upewnić, jest subProjects / reallyCoolProject1 / build.gradle, które ma apply plugin: "android-library"zamiast apply plugin: "android".

Jak każdy projekt Gradle (i Maven), musimy teraz powiedzieć projektowi root o jego zależności. Może to również obejmować dowolne normalne zależności Java, które chcesz.

build.gradle

dependencies{
    compile 'com.fasterxml.jackson.core:jackson-core:2.1.4'
    compile 'com.fasterxml.jackson.core:jackson-databind:2.1.4'
    compile project(":subProjects:reallyCoolProject1")
    compile project(':subProjects:reallyCoolProject2')
}

Wiem, że to wygląda na wiele kroków, ale są one dość łatwe, gdy zrobisz to raz lub dwa razy. W ten sposób możesz również budować na serwerze CI, zakładając, że masz tam zainstalowany Android SDK.

Uwaga boczna NDK: Jeśli zamierzasz używać NDK, będziesz potrzebować czegoś takiego jak poniżej. Przykładowy plik build.gradle można znaleźć tutaj: https://gist.github.com/khernyo/4226923

build.gradle

task copyNativeLibs(type: Copy) {
    from fileTree(dir: 'libs', include: '**/*.so' )  into  'build/native-libs'
}
tasks.withType(Compile) { compileTask -> compileTask.dependsOn copyNativeLibs }

clean.dependsOn 'cleanCopyNativeLibs'

tasks.withType(com.android.build.gradle.tasks.PackageApplication) { pkgTask ->
  pkgTask.jniDir new File('build/native-libs')
}

Źródła:

  1. http://tools.android.com/tech-docs/new-build-system/user-guide
  2. https://gist.github.com/khernyo/4226923
  3. https://github.com/ethankhall/driving-time-tracker/
Ethan
źródło
1
Dzięki @Ethan, to wypełnia niektóre luki. W Android Studio brakowało tylko głównego projektu build.gradle. Zaktualizuję pytanie o błąd, który teraz otrzymuję.
respectTheCode
1
Próbowałem sklonować repozytorium śledzenia czasu jazdy i zaimportować projekt, ale nie można go skompilować.
respectTheCode
Zapomniałem o czymś, złożyłem nową prośbę
Ethan
1
Cześć @Ethan, wygląda na to, że masz doświadczenie z Gradle, czy mógłbyś pomóc również w moim problemie: stackoverflow.com/questions/17479076/ ...
TacB0sS
@Ethan Czy możesz pomóc w rozwiązaniu problemu z zależnościami w Gradle na Androida?
JJD
6

Właśnie miałem bardzo podobne problemy z budowaniem Gradle / dodawaniem biblioteki .jar. Mam to działające przez kombinację:

  1. Przeniesienie folderu libs do katalogu głównego projektu (ten sam katalog co „src”) i dodanie biblioteki do tego folderu w programie Finder (w systemie Mac OS X)
  2. W Android Studio kliknij prawym przyciskiem myszy folder, aby dodać go jako bibliotekę
  3. Edycja zależności w pliku build.gradle, dodanie compile fileTree(dir: 'libs', include: '*.jar')}

ALE co ważniejsze i irytujące, zaledwie kilka godzin po uruchomieniu Android Studio właśnie wypuściło 0.3.7, które twierdzi, że rozwiązało wiele problemów z gradle, takich jak dodanie bibliotek .jar

http://tools.android.com/recent

Mam nadzieję, że to pomaga ludziom!

Joel Balmer
źródło
1
Ten problem dotyczy bibliotek Andriod, a nie bibliotek Java .jar.
szacunekTheCode
2
Prawdziwe! Jednak mój problem dotyczył kompilacji Gradle i studia Android, a ten post był na tyle podobny, że pomógł mi doprowadzić mnie do mojego rozwiązania - po prostu pomyślałem, że rozpowszechniłem dobre wieści na wypadek, gdyby ktoś inny został poprowadzony do tego pytania i był w tej samej sytuacji mnie.
Joel Balmer
1

Oto moje rozwiązanie dla użytkowników Mac, myślę, że działa również dla okna:

Najpierw przejdź do paska narzędzi Android Studio

Kompilacja> Utwórz projekt (gdy jesteście online, pozwólcie mu pobrać pliki), a następnie

Kompiluj> Kompiluj Moduł „nazwa Twojej aplikacji jest wyświetlana tutaj” (nadal online niech pliki zostaną
pobrane i zakończone), a następnie

Uruchom aplikację, po czym uruchomi emulator i skonfiguruje go, a następnie uruchomi!

To jest to!!! Szczęśliwi ludzie z kodowania !!!!!!!

Henula
źródło
0

Gradle Build Tools 2.2.0+ - wszystko po prostu działa

To jest właściwy sposób, aby to zrobić

Próbując uniknąć eksperymentów i szczerze mówiąc, mam dość NDK i wszystkich jego hackerów, cieszę się, że pojawiło się 2.2.x Gradle Build Tools i teraz po prostu działa. Kluczem jest argument path externalNativeBuildi wskazujący ndkBuildargument path na Android.mklub change ndkBuilddo cmakei wskazujący argument path na CMakeLists.txtskrypcie budowania.

android {
    compileSdkVersion 19
    buildToolsVersion "25.0.2"

    defaultConfig {
        minSdkVersion 19
        targetSdkVersion 19

        ndk {
            abiFilters 'armeabi', 'armeabi-v7a', 'x86'
        }

        externalNativeBuild {
            cmake {
                cppFlags '-std=c++11'
                arguments '-DANDROID_TOOLCHAIN=clang',
                        '-DANDROID_PLATFORM=android-19',
                        '-DANDROID_STL=gnustl_static',
                        '-DANDROID_ARM_NEON=TRUE',
                        '-DANDROID_CPP_FEATURES=exceptions rtti'
            }
        }
    }

    externalNativeBuild {
        cmake {
             path 'src/main/jni/CMakeLists.txt'
        }
        //ndkBuild {
        //   path 'src/main/jni/Android.mk'
        //}
    }
}

Aby uzyskać więcej szczegółów, sprawdź stronę Google dotyczącą dodawania kodu natywnego .

Po prawidłowym skonfigurowaniu możesz ./gradlew installDebugi gotowe. Musisz również mieć świadomość, że NDK przechodzi do clang, ponieważ gcc jest teraz przestarzałe w Android NDK.

Cameron Lowell Palmer
źródło