Como construir uma biblioteca Android com Android Studio e gradle?

144

Estou tentando migrar um projeto do Eclipse, mas nada que tentei está funcionando. No Eclipse, tenho 3 projetos (2 projetos de aplicativos para Android e 1 projeto de biblioteca para Android). Os 2 projetos de aplicativos dependem do projeto da biblioteca. Quando faço a exportação do gradle, recebo 3 projetos que não funcionam. Estou aberto à reestruturação do projeto, mas não encontrei nenhuma documentação sobre como isso deve ser feito.

Existe uma maneira de fazer com que os três projetos que as exportações do Eclipse funcionem juntos? Estou melhor reestruturando as coisas e, em caso afirmativo, há documentação sobre como isso deve ser feito?

Atualizar

Fiz o upload de todo o projeto no GitHub https://github.com/respectTheCode/android-studio-library-example

Atualização 1

Com base nas sugestões de Padma Kumar, é isso que tentei.

  1. Crie um novo projeto chamado MyApp
  2. Clique File > New Module, escolha Android Librarye nomeie-oMyLib
  3. Clique Build > Make Project

A construção falha com este erro

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.

Em seguida, adicionei um packageatributo ao manifesto, tornando-o

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

Após a construção, recebo este erro

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

Adicionar dependência não parece ter nenhum impacto no erro. Continuando de cima

  1. Clique File > Project Structure > Modules > MyApp-MyApp
  2. Mudar para o Dependenciesseparador
  3. Clique + > Module Dependencye escolhaMyLib
  4. Clique ApplyeOK
  5. Clique Build > Make Project

Atualização 2

Com base nas sugestões de Ethan, é aqui que chegamos

O sub-projeto 2 build.gradleparece ter todas as partes corretas e a única diferença é a linha de plug-in abaixo 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
    }
}

O projeto raiz build.gradleestava vazio, então eu adicionei os dois projetos como este

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

Agora recebo esse erro ao criar

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.

Atualização 3

Muito obrigado Ethan por resolver isso.

  1. Adicione compile project(':SubProjects:MyLib')aoMyLib/build.gradle
  2. Retire compile files('libs/android-support-v4.jar')doMyLib/build.gradle
  3. Feche o projeto e importe o projeto raiz da gradle

Atualização 4

A partir da versão 0.1.2, agora você pode incluir em compile "com.android.support:support-v4:13.0.0"vez de compile files('libs/android-support-v4.jar'). Como é proveniente do mavin, agora você pode incluí-lo em vários projetos sem problemas.

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

Atualização 5

A partir da versão 0.1.3, agora existe um botão "Sync Project" na barra de ferramentas. Você pode clicar nele em vez de reimportar seu projeto depois de fazer alterações nos .gradlearquivos.

respectTheCode
fonte
Fiz uma solicitação de recebimento para o seu projeto no github. Houve duas mudanças simples. Remova o conteúdo do seu /build.gradle. {Fiz isso porque você não definiu que tipo de projeto era; portanto, estava reclamando de não saber o que fazer com ele}; em seguida, adicionei a dependência de: SubProject: MyLib para: SubProject: MyApp. Em seguida, executei ./gradlew: SubProject: MyApp: iD (o iD mapeia o installDebug). Eu também tive que remover as libs / android-support-v4.jar duplicadas. Como não é uma dependência 'real', você não pode tê-la em dois lugares.
Ethan
Comentei a solicitação de recebimento. github.com/respectTheCode/android-studio-library-example/pull/1
respectTheCode 23/13/13
1
Vale ressaltar, se você adicionar compile 'com.google.android:support-v4:r6'a cada um de seus projetos e o plug-in maven (como no exemplo build.gradle abaixo) em vez do compile files('libs/android-support-v4.jar')gradle, perceberá que os dois projetos incluem a mesma coisa e a incluirão apenas uma vez.
Ethan
@respectTheCode Enviei uma solicitação pull para limpar um pouco seu projeto de exemplo no github. Obrigado por compartilhar!
precisa saber é o seguinte
Possível duplicado de estúdio Android, Gradle e NDK
Cameron Lowell Palmer

Respostas:

115

Nota : Esta resposta é uma resposta pura do Gradle, eu a uso regularmente no IntelliJ, mas não sei como é a integração com o Android Studio. Acredito em saber o que está acontecendo comigo, e é assim que uso Gradle e Android.

Exemplo completo de TL; DR - https://github.com/ethankhall/driving-time-tracker/

Disclaimer : Este é um projeto em que estou / estava trabalhando.

Gradle tem uma estrutura definida (que você pode alterar, o link na parte inferior explica como) que é muito semelhante ao Maven, se você já o usou.

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

Se você tiver apenas um projeto, o arquivo settings.gradle não será necessário. No entanto, você deseja adicionar mais projetos, por isso precisamos dele.

Agora, vamos dar uma olhada no arquivo build.gradle. Você precisará disso (para adicionar as ferramentas do Android)

build.gradle

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

Agora precisamos contar a Gradle sobre algumas partes do Android. É bem simples. Um básico (que funciona na maioria dos meus casos) se parece com o seguinte. Eu tenho um comentário neste bloco, ele permitirá que eu especifique o nome e o código da versão ao gerar o APK.

build.gradle

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

Algo que queremos adicionar, para ajudar alguém que ainda não viu a luz de Gradle, uma maneira de usar o projeto sem instalá-lo.

build.gradle

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

Então agora temos um projeto para construir. Agora vamos adicionar os outros. Coloquei-os em um diretório, talvez chame de deps ou subProjects. Realmente não importa, mas você precisará saber onde colocar. Para informar a Gradle onde estão os projetos, você precisará adicioná-los ao settings.gradle.

Estrutura de Diretórios:

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'

A última coisa que você deve garantir é o subProjects / reallyCoolProject1 / build.gradle , em apply plugin: "android-library"vez de apply plugin: "android".

Como todo projeto Gradle (e Maven), agora precisamos informar o projeto raiz sobre sua dependência. Isso também pode incluir quaisquer dependências Java normais que você deseja.

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

Eu sei que isso parece ser uma série de etapas, mas elas são bem fáceis quando você faz uma ou duas vezes. Dessa forma, você também poderá criar um servidor de IC, desde que o Android SDK esteja instalado lá.

Nota lateral do NDK: Se você for usar o NDK, precisará de algo como abaixo. Exemplo de arquivo build.gradle pode ser encontrado aqui: 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')
}

Fontes:

  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
fonte
1
Obrigado @Ethan, isso preenche alguns dos espaços em branco. O Android Studio estava ausente no projeto raiz build.gradle. Atualizarei a pergunta com o erro que estou recebendo agora.
respectTheCode
1
Tentei clonar seu repositório de rastreador de tempo de condução e importar o projeto, mas ele não seria compilado.
respectTheCode
Eu esqueci algo, eu fiz um novo pedido
Ethan
1
Oi @Ethan, parece que você tem experiência com Gradle, você se importaria de ajudar com o meu problema assim: stackoverflow.com/questions/17479076/...
TacB0sS
@ Ethan Você pode ajudar com um problema de dependência do Gradle para Android, por favor?
JJD
6

Eu apenas tive problemas muito semelhantes com o gradle builds / adicionando a biblioteca .jar. Eu consegui trabalhar com uma combinação de:

  1. Movendo a pasta libs até a raiz do projeto (mesmo diretório que 'src') e adicionando a biblioteca a essa pasta no localizador (usando o Mac OS X)
  2. No Android Studio, clique com o botão direito do mouse na pasta para adicionar como biblioteca
  3. Editando as dependências no arquivo build.gradle, adicionando compile fileTree(dir: 'libs', include: '*.jar')}

MAS, o que é mais importante e irritante, apenas algumas horas depois que eu funciono, o Android Studio acaba de lançar o 0.3.7, que afirma ter resolvido muitos problemas graduais, como a adição de bibliotecas .jar

http://tools.android.com/recent

Espero que isso ajude as pessoas!

Joel Balmer
fonte
1
Esse problema está falando das bibliotecas Andriod e não das bibliotecas Java .jar.
respectTheCode 4/13/13
2
Verdade! No entanto, meu problema envolveu compilações de gradle e o estúdio android, e este post foi semelhante o suficiente para me ajudar a encontrar minha solução - apenas pensei em espalhar as boas notícias caso alguém fosse levado a essa pergunta e estava na mesma posição mim.
Joel Balmer
1

Aqui está a minha solução para usuários de mac, acho que também funciona para a janela:

Primeiro, acesse a barra de ferramentas do Android Studio

Build> Make Project (enquanto vocês estão online, deixe-os baixar os arquivos) e depois

Módulo Build> Compile "o nome do seu aplicativo é mostrado aqui" (ainda online, permita que os arquivos sejam
baixados e finalizados) e depois

Execute o aplicativo que está pronto, ele iniciará o emulador e o configurará e, em seguida, execute-o!

É isso!!! Feliz pessoal de codificação !!!!!!!

Henula
fonte
0

Gradle Build Tools 2.2.0+ - Tudo simplesmente funciona

Esta é a maneira correta de fazer isso

Ao tentar evitar o experimental e francamente farto do NDK e de todos os seus hackers, estou feliz que o 2.2.x do Gradle Build Tools tenha sido lançado e agora funciona. A chave é o externalNativeBuilde apontando ndkBuildargumento de caminho a uma Android.mkou a mudança ndkBuildpara cmakee aponte o argumento de caminho em um CMakeLists.txtscript de construção.

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

Para muito mais detalhes, consulte a página do Google sobre a adição de código nativo .

Após a configuração correta, você pode ./gradlew installDebuge pronto. Você também precisará estar ciente de que o NDK está mudando para clang, pois o gcc agora está obsoleto no Android NDK.

Cameron Lowell Palmer
fonte