Android studio, gradle e NDK


153

Sou muito novo em todo esse suporte e no Android Studio. Consegui converter meu projeto Android para gradle usando a opção de exportação.

Mas estou procurando alguma documentação ou ponto de partida para integrar a compilação NDK ao processo de compilação gradle.

Se possível, também preciso de algum tipo de estágio "depois" que copie os binários de construção (arquivos .so) no diretório de ativos.


Eu afixei minha resposta no link abaixo mencionado stackoverflow.com/questions/20900814/...
Ahmad Ali Nasir

24
Novos leitores: saiba que essa pergunta foi feita inicialmente durante o período beta do Android Studio; a resposta mudou com o tempo. Preste atenção à versão Gradle mencionada nas respostas, bem como quando as respostas foram realmente postadas.
Sean Beach

Se algo realmente muda vou editar a pergunta para relect o status
plaisthos

O Android Studio 1.3 no canal canary suporta totalmente o NDK. Referência: tools.android.com/download/studio/canary/latest
Vikasdeep Singh

18 de junho de 2015: o Android Studio 1.3 Beta já está disponível no canal beta! Desculpe, essa compilação ainda não contém o suporte C / C ++; fonte: tools.android.com/recent/androidstudio13betaavailable
fastr.de 20/06/2015

Respostas:


85

Lançamos uma primeira versão da integração como uma prévia no 1.3: http://tools.android.com/tech-docs/android-ndk-preview

A integração permanecerá uma visualização mesmo depois que a 1.3 se tornar final. Nenhum ETA atual sobre quando será final (a partir de 10/07/2015).

Mais informações aqui: http://tools.android.com/tech-docs/android-ndk-preview


2
Seria ótimo se eu poderia usar NDK e conclusão de comando com a depuração sob Android Studio (e Gradle suporte)
powder366

1
@GREnvoy - Como configuramos o construtor NDK certo no estúdio Android? Você pode me dar os passos? :)
Shravan

7
@DirtyBeach Por que está desatualizado? Ainda não há uma integração do NDK no Studio. Estamos trabalhando nisso, mas não há ETA no momento.
Xavier Ducrohet 27/01

2
Minha ação foi baseada em como eu estava definindo "integração". Entendi que significa "uma maneira de usar o NDK com gradle", que agora existe, embora nenhum deles seja uma solução fantástica. No entanto, com base no seu comentário, parece que sua equipe tem outra coisa em mente sobre o que poderia ser uma verdadeira integração. Eu retiro minha declaração anterior.
Sean Beach

2
A integração do NDK foi anunciada durante o Google IO 2015. Está disponível no Android Studio 1.3 (a visualização pode ser baixada em breve. Vou postar um link quando estiver disponível).
Cypress Frankenfeld

43

ATUALIZAÇÃO: O Android Studio com suporte a NDK já está disponível: http://tools.android.com/tech-docs/android-ndk-preview

Para criar com um script, a solução gradle abaixo deve funcionar:

Estou usando meu script de construção e adicionado ao meu arquivo (parece funcionar 0.8+): isso parece ser equivalente à solução abaixo (mas parece melhor no arquivo gradle):

 android {
    sourceSets {
        main {
            jniLibs.srcDirs = ['native-libs']
            jni.srcDirs = [] //disable automatic ndk-build
        }
    }
 }

Infelizmente, a compilação não falha se o diretório não estiver presente ou não contiver .soarquivos.


5
Isso não funciona mais com a nova versão do Android Studio, solução alternativa?
powder366

@ powder366 Veja minha resposta.
Leandros

2
Um pouco de magia Groovy: tasks.withType(com.android.build.gradle.tasks.PackageApplication) { it.jniFolders = [file("libs")] as Set }. Obrigado pela ajuda!
trnL

Qual é o procedimento para o Android Studio 0.8.9
Pandiri Deepak

1
@plaisthos Muito obrigado por apontar a direção certa! A segunda linha do script gradle jni.srcDirs = [] //disable automatic ndk-buildé muito importante, pois impede o Android Studio de reconstruir o código-fonte C / C ++. Estou tentando descobrir isso há dois dias, até que vi sua postagem e isso resolveu meu problema. Eu realmente acho que a compilação NDK é melhor criada separadamente apenas pelo makefile da linha de comando Android.mk, não pelo script gradle, já que o C / C ++ foi criado pelo Makefile por mais de 40 anos!
tonga

40

Com a atualização do Android Studio para 1.0, o suporte à cadeia de ferramentas NDK melhorou imensamente ( nota: leia minhas atualizações na parte inferior desta postagem para ver o uso com o novo plugin experimental Gradle e o Android Studio 1.5 ).

O Android Studio e o NDK estão integrados o suficiente para que você apenas precise criar um bloco ndk {} no build.gradle do seu módulo e defina seus arquivos de origem no diretório (module) / src / main / jni - e você feito!

Chega de ndk-build a partir da linha de comando.

Eu escrevi tudo sobre isso no meu blog aqui: http://www.sureshjoshi.com/mobile/android-ndk-in-android-studio-with-swig/

Os pontos salientes são:

Há duas coisas que você precisa saber aqui. Por padrão, se você possui bibliotecas externas que deseja carregar no aplicativo Android, elas são procuradas no (módulo) / src / main / jniLibs por padrão. Você pode alterar isso usando a configuração sourceSets.main.jniLibs.srcDirs no build.gradle do seu módulo. Você precisará de um subdiretório com bibliotecas para cada arquitetura segmentada (por exemplo, x86, arm, mips, arm64-v8a, etc ...)

O código que você deseja compilar por padrão pela cadeia de ferramentas NDK estará localizado em (módulo) / src / main / jni e, da mesma forma que acima, você pode alterá-lo definindo sourceSets.main.jni.srcDirs no build.gradle do seu módulo

e coloque isso no build.gradle do seu módulo:

ndk {
  moduleName "SeePlusPlus" // Name of C++ module (i.e. libSeePlusPlus)
  cFlags "-std=c++11 -fexceptions" // Add provisions to allow C++11 functionality
  stl "gnustl_shared" // Which STL library to use: gnustl or stlport
}

Esse é o processo de compilação do código C ++, a partir daí você precisa carregá-lo e criar wrappers - mas, a julgar pela sua pergunta, você já sabe como fazer tudo isso, para que eu não volte a usar o hash.

Além disso, coloquei um repositório Github deste exemplo aqui: http://github.com/sureshjoshi/android-ndk-swig-example

ATUALIZAÇÃO: 14 de junho de 2015

Quando o Android Studio 1.3 for lançado, deve haver um suporte melhor ao C ++ por meio do plug-in JetBrains CLion. Atualmente, estou no pressuposto de que isso permitirá o desenvolvimento de Java e C ++ no Android Studio; no entanto, acho que ainda precisamos usar a seção Gradle NDK, como afirmei acima. Além disso, acho que ainda haverá a necessidade de gravar arquivos wrapper Java <-> C ++, a menos que o CLion os faça automaticamente.

ATUALIZAÇÃO: 5 de janeiro de 2016

Atualizei meu blog e o repositório do Github (no ramo de desenvolvimento) para usar o Android Studio 1.5 com o mais recente plugin experimental Gradle (0.6.0-alpha3).

http://www.sureshjoshi.com/mobile/android-ndk-in-android-studio-with-swig/ http://github.com/sureshjoshi/android-ndk-swig-example

A compilação Gradle para a seção NDK agora se parece com isso:

android.ndk {
    moduleName = "SeePlusPlus" // Name of C++ module (i.e. libSeePlusPlus)
    cppFlags.add("-std=c++11") // Add provisions to allow C++11 functionality
    cppFlags.add("-fexceptions")
    stl = "gnustl_shared" // Which STL library to use: gnustl or stlport
}

Além disso, surpreendentemente, o Android Studio possui preenchimento automático para C ++ - wrappers gerados em Java usando a palavra-chave 'native':

Exemplo de preenchimento automático de C ++ - wrapper Java

No entanto, não é totalmente otimista ... Se você estiver usando o SWIG para quebrar uma biblioteca para gerar automaticamente o código e, em seguida, tentar usar a geração automática de palavras-chave nativas, ele colocará o código no lugar errado no seu swig _wrap .cxx ... Então você precisa movê-lo para o bloco "extern C":

Wrapper Java movido para o local correto

ATUALIZAÇÃO: 15 de outubro de 2017

Seria negligente se não mencionasse que o Android Studio 2.2 em diante tem essencialmente suporte 'nativo' (sem trocadilhos) para a cadeia de ferramentas NDK via Gradle e CMake. Agora, quando você cria um novo projeto, basta selecionar o suporte ao C ++ e pronto.

Você ainda precisará gerar seu próprio código de camada JNI ou usar a técnica SWIG que mencionei acima, mas o andaime de um projeto C ++ no Android é trivial agora.

As alterações no arquivo CMakeLists (onde você coloca seus arquivos de origem C ++) serão capturadas pelo Android Studio e recompilarão automaticamente todas as bibliotecas associadas.


1
Coloque o * .so em (módulo) / src / main / jniLibs
fawkes

por isso é NDEBUG sempre definido ao usar Android Studio, mesmo em compilações de depuração
pt123

35

No Google IO 2015, o Google anunciou a integração completa do NDK no Android Studio 1.3.

Agora está fora de visualização e disponível para todos: https://developer.android.com/studio/projects/add-native-code.html

Resposta antiga: o Gradle liga automaticamente ndk-buildse você tiver um jnidiretório nas fontes do projeto.

Isso está funcionando no Android studio 0.5.9 (canary build).

  1. Faça o download do NDK

  2. Adicione ANDROID_NDK_HOMEàs variáveis ​​de ambiente ou ndk.dir=/path/to/ndkao seu local.propertiesno seu projeto do Android Studio. Isso permite que o Android studio execute o ndk automaticamente.

  3. Faça o download dos projetos de amostra gradle mais recentes para ver um exemplo de projeto ndk. (Eles estão na parte inferior da página). Um bom exemplo de projeto é ndkJniLib.

  4. Copie o gradle.builddos projetos de amostra NDK. Será algo parecido com isto. Isso gradle.buildcria um apk diferente para cada arquitetura. Você deve selecionar qual arquitetura deseja usar no build variantspainel. painel de variantes de criação

    apply plugin: 'android'
    
    dependencies {
        compile project(':lib')
    }
    
    android {
        compileSdkVersion 19
        buildToolsVersion "19.0.2"
    
        // This actual the app version code. Giving ourselves 100,000 values [0, 99999]
        defaultConfig.versionCode = 123
    
        flavorDimensions "api", "abi"
    
        productFlavors {
            gingerbread {
                flavorDimension "api"
                minSdkVersion 10
                versionCode = 1
            }
            icecreamSandwich {
                flavorDimension "api"
                minSdkVersion 14
                versionCode = 2
            }
            x86 {
                flavorDimension "abi"
                ndk {
                    abiFilter "x86"
                }
                // this is the flavor part of the version code.
                // It must be higher than the arm one for devices supporting
                // both, as x86 is preferred.
                versionCode = 3
            }
            arm {
                flavorDimension "abi"
                ndk {
                    abiFilter "armeabi-v7a"
                }
                versionCode = 2
            }
            mips {
                flavorDimension "abi"
                ndk {
                    abiFilter "mips"
                }
                versionCode = 1
            }
            fat {
                flavorDimension "abi"
                // fat binary, lowest version code to be
                // the last option
                versionCode = 0
            }
        }
    
        // make per-variant version code
        applicationVariants.all { variant ->
            // get the version code of each flavor
            def apiVersion = variant.productFlavors.get(0).versionCode
            def abiVersion = variant.productFlavors.get(1).versionCode
    
            // set the composite code
            variant.mergedFlavor.versionCode = apiVersion * 1000000 + abiVersion * 100000 + defaultConfig.versionCode
        }
    
    }

Observe que isso ignorará seus arquivos Android.mk e Application.mk. Como solução alternativa, você pode dizer ao gradle para desativar a chamada atuomatic do ndk-build e especificar o diretório das fontes do ndk manualmente.

sourceSets.main {
    jniLibs.srcDir 'src/main/libs' // use the jni .so compiled from the manual ndk-build command
    jni.srcDirs = [] //disable automatic ndk-build call
}

Além disso, você provavelmente desejará chamar o ndk-build em seu script gradle build explicitamente, porque acabou de desativar a chamada automática.

task ndkBuild(type: Exec) {
   commandLine 'ndk-build', '-C', file('src/main/jni').absolutePath
}

tasks.withType(JavaCompile) {
    compileTask -> compileTask.dependsOn ndkBuild
}

Sim. Mas isso só funciona em plataformas Unix e também é limitado se você for mais complexo do que uma configuração / makefiles ndk muito simples.
plaisthos

Sim, ele gerará automaticamente makefiles para as coisas limitadas que você pode definir no arquivo de construção gradle, no entanto, há uma solução alternativa. Eu adicionei à minha resposta.
Cypress Frankenfeld

1
A chamada para o ndk-build só funcionará na linha de comando e não no Android Studio.
Cameron Lowell Palmer

Embora essa não seja a resposta mais recente, parece provável que seja a mais precisa. Preste atenção especial à etapa 3: "Faça o download dos últimos projetos de amostra de gradle".
Sean Praia

4
Eu uso esse truque em vez de desativar dir src para que eu possa editar C / C ++ arquivos dentro do IDEtasks.all { task -> if (task.name.contains('Ndk')) task.enabled = false }
sherpya

23

Eu encontrei "gradle 1.11 com.android.tools.build:gradleAdd.9.+" agora suporta ndk de pré-compilação, basta colocar o * .so no diretório src / main / jniLibs. ao construir o gradle, empacote o ndk no lugar certo.

aqui está o meu projeto

Projeto:
| --src
| - | --main
| - | - | --java
| - | - | --jniLibs
| - | - | - | --armeabi
Arquivos | - | - | - | - | -. so
| --libs
| - | --other.jar


16

A partir de agora (Android Studio v0.8.6), é bastante simples. Aqui estão as etapas para criar um aplicativo do tipo "Olá, mundo":

  1. Baixe o NDK do Android e coloque a pasta raiz em algum lugar saudável - no mesmo local da pasta SDK, talvez.

  2. Adicione o seguinte ao seu local.properties arquivo: ndk.dir=<path-to-ndk>

  3. Adicione o seguinte ao seu arquivo build.gradle dentro do diretório defaultConfig fechamento, logo após a versionNamelinha:ndk { moduleName="hello-world" }

  4. Nos módulos do seu aplicativo main diretório , crie uma nova pasta chamada jni.

  5. Nessa pasta, crie um arquivo chamado hello-world.c , que você verá abaixo.

  6. Veja o Activitycódigo de exemplo abaixo para obter um exemplo de como chamar um método (ou é uma função?) Em hello-world.c.


hello-world.c

#include <string.h>
#include <jni.h>

jstring
Java_me_mattlogan_ndktest_MainActivity_stringFromJNI(JNIEnv* env, jobject thiz)
{
    return (*env)->NewStringUTF(env, "Hello world!");
}

MainActivity.java

public class MainActivity extends Activity {

    static {
        System.loadLibrary("hello-world");
    }

    public native String stringFromJNI();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        String testString = stringFromJNI();

        TextView mainText = (TextView) findViewById(R.id.main_text);
        mainText.setText(testString);
    }
}

build.gradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion 20
    buildToolsVersion "20.0.0"

    defaultConfig {
        applicationId "me.mattlogan.ndktest"
        minSdkVersion 15
        targetSdkVersion 20
        versionCode 1
        versionName "1.0"

        ndk {
            moduleName "hello-world"
        }
    }
    buildTypes {
        release {
            runProguard false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
}

Encontre o código fonte completo de um aplicativo muito semelhante aqui (menos o NDK).


Estou fazendo exatamente as instruções no meu projeto atual, mas o material NDK ainda não está sendo construído. Alguma ideia? Parece que está construindo tudo o resto, mas apenas pulando o material de jni.
precisa saber é o seguinte

@NannuoLei obrigado, tentei, mas estou tendo um problema em que o .so não está sendo gerado. Tudo o resto parece funcionar, mas quando executo o apkg no emulador, ele reclama que não pode carregar o objeto compartilhado.
Aaa90210

@ aaa90210 é o seu emulador baseado em uma imagem x86? Por padrão NDK só vai produzir uma biblioteca ARMEABI, se você quiser construir uma imagem x86 você pode adicionar esta linha em Application.mk: APP_ABI: = armeabi x86
Leo suporta Monica Cellio

1
funcionou comigo. PS: quem vê esta resposta, não se esqueça de mudar Java_me_mattlogan_ndktest_MainActivity_stringFromJNIpara o seu próprio :) :)
AbdulMomen

8

Se você está no unix, a versão mais recente (0.8) adiciona o ndk-build. Veja como adicioná-lo:

android.ndk {
    moduleName "libraw"
}

Ele espera encontrar o JNI em 'src / main / jni', caso contrário, você pode defini-lo com:

sourceSets.main {
    jni.srcDirs = 'path'
}

A partir de 28 de janeiro de 2014, com a versão 0.8, a compilação estava quebrada no Windows, você deve desabilitar a compilação com:

sourceSets.main {
    jni.srcDirs = [] //disable automatic ndk-build call (currently broken for windows)
}

1
Existe alguma documentação para esse recurso? Não encontrei nenhum. No momento em que parece ignorar completamente o meu Android.mk/Application.mk.
plaisthos

Eu não encontrei nenhum. Pode ter entrado na compilação pela metade. Estou no Windows, então só posso confirmar que ele falha ao tentar chamar o script nix-build do unix. Não haveria outro motivo para chamar isso e integrar a compilação nativa em gradle. Você está no unix?
Anthony


ele realmente espera encontrar pré-construídos * arquivos .so em jniLibs.srcDirs
Alpine

Eu discordo com base no fato de que ele falha ao chamar o ndk-build, o que absolutamente não é necessário se exigir bibliotecas construídas. Não posso confirmar, pois não tenho tempo para vm Linux no momento.
8134 Anthony

7

Uma solução alternativa elegante é mostrada em https://groups.google.com/d/msg/adt-dev/nQobKd2Gl_8/Z5yWAvCh4h4J .

Basicamente, você cria um jar que contém "lib / armeabi / yourlib.so" e depois inclui o jar na compilação.


Sim. Isso só funciona bem se você não alterar seu código nativo frequentemente. E você terá que incluir arquivos jar binários no repositório. Caso contrário, você terminará com um script de construção que cria um jar on-line.
plaisthos

1
Eu modificado exemplo Olá-JNI do Android com um simples script bash que envolve ndk-build, gera .jars para cada .soe os coloca em caminho de construção de Gradle para aliviar essa dor. Confira.
Dll 17/10

4

Uma boa resposta para automatizar o empacotamento de .soarquivos- prontamente compilados é fornecida em outro thread (fechado) . Para fazer isso funcionar, tive que mudar de linha:

from fileTree(dir: 'libs', include: '**/*.so')

para dentro:

from fileTree(dir: 'src/main/libs', include: '**/*.so') 

Sem essa alteração, os .soarquivos não foram encontrados e, portanto, a tarefa de empacotá-los nunca seria executada.


Atualização: observe que no Android Studios mais recente (pelo menos na versão 1.5) o código nativo é muito melhor incorporado e não é necessário executar esta tarefa separada para compactar seu código.
HYS

4

A resposta de @plaisthos quebrou na versão mais recente do gradle, mas ainda há uma maneira de fazê-lo. Crie umnative-libs diretório na raiz do diretório do seu projeto e copie todas as nossas bibliotecas para esse diretório.

Adicione as seguintes linhas ao seu build.gradle. Construa e seja feliz.

task copyNativeLibs(type: Copy) {
    from(new File(project(':<your project>').getProjectDir(), 'native-libs')) { include '**/*.so' }
    into new File(buildDir, 'native-libs')
}

tasks.withType(Compile) { compileTask -> compileTask.dependsOn copyNativeLibs }

clean.dependsOn 'cleanCopyNativeLibs'

3

Este é o código que eu uso para construir usando o android-ndk da gradle. Para isso, adicione o caminho do diretório ndk em gradle.propertiesie. adicione ndkdir=/home/user/android-ndk-r9de coloque todos os arquivos jni em uma pasta native, src/main/como você pode ver no código postado abaixo. Ele criará jar com bibliotecas nativas que você pode usar normalmente como emSystem.loadLibrary("libraryname");

dependencies {
    compile fileTree(dir: "$buildDir/native-libs", include: '*.jar')
}

task ndkBuild(type: Exec) {
    commandLine "$ndkdir/ndk-build", "--directory", "$projectDir/src/main/native", '-j', Runtime.runtime.availableProcessors(),
            "APP_PLATFORM=android-8",
            "APP_BUILD_SCRIPT=$projectDir/src/main/native/Android.mk",
            "NDK_OUT=$buildDir/native/obj",
            "NDK_APP_DST_DIR=$buildDir/native/libs/\$(TARGET_ARCH_ABI)"
}

task nativeLibsToJar(type: Jar, description: 'create a jar with native libs') {
    destinationDir file("$buildDir/native-libs")
    baseName 'native-libs'
    from fileTree(dir: "$buildDir/native/libs", include: '**/*.so')
    into 'lib/'
}

tasks.withType(JavaCompile) {
    compileTask -> compileTask.dependsOn nativeLibsToJar
}

nativeLibsToJar.dependsOn 'ndkBuild'

3

Usei o código a seguir para compilar bibliotecas nativas de caixas de depósito, estou usando o Android Studio v1.1.

task nativeLibsToJar(type: Zip) {
    destinationDir file("$buildDir/native-libs")
    baseName 'native-libs'
    extension 'jar'
    from fileTree(dir: 'src/main/libs', include: '**/*.so')
    into 'lib/'
}

tasks.withType(JavaCompile) {
    compileTask -> compileTask.dependsOn(nativeLibsToJar)
}


1

Para expandir o que Naxos disse (obrigado Naxos por me enviar na direção certa!), Aprendi bastante com os exemplos NDK lançados recentemente e postei uma resposta em uma pergunta semelhante aqui.

Como configurar o NDK com o plugin Android Gradle 0.7

Esta postagem contém detalhes completos sobre como vincular bibliotecas nativas pré-criadas ao seu aplicativo para as várias arquiteturas, além de informações sobre como adicionar suporte NDK diretamente ao script build.gradle. Na maioria das vezes, você não precisa mais trabalhar com o zip e a cópia.


1

Aqui estão as etapas que eu usei para fazer o NDK funcionar no meu projeto do Android Studio. Usei este tutorial para me ajudar https://software.intel.com/pt-br/videos/using-the-ndk-with-android-studio

Para usar o NDK, você deve adicionar uma linha NDK ao local.properties. Então, sob o seu sdk.dir, adicione

ndk.dir=C\:\\MyPathToMyNDK\ndk

Nos meus aplicativos build.gradle, tenho o seguinte código

        ndk {
            moduleName "myLib"
            ldLibs "log"
            stl "gnustl_shared"
            cFlags "-std=c++11 -frtti -fexceptions -pthread"
        }

moduleName é o nome que você deseja fornecer ao seu código nativo. Eu acredito que é assim que a biblioteca compartilhada será chamada. O ldLibs permite que eu faça logon no LogCat, stl é o stl que você deseja importar. Existem muitas opções, iguais ao NDK do Eclipse. ( http://www.kandroid.org/ndk/docs/CPLUSPLUS-SUPPORT.html )

cFlags ainda são uma certa quantidade de magia negra para mim. Não encontrei uma boa fonte para todas as opções e o que elas me dão. Pesquise em torno do StackOverflow o que você precisa, é onde eu o encontrei. Eu sei que o c ++ 11 me permite usar o novo padrão do c ++ 11.

Aqui está um exemplo de como eu registro no LogCat a partir do código nativo

__android_log_print(ANDROID_LOG_DEBUG, "TestApp", "Adding - String %d has a field name of %s and a value of %s", i, lKeyUTF8.c_str(), lValueUTF8.c_str());

1

configurar projeto no android studio a partir do eclipse: você precisa importar o projeto eclipse ndk para o android studio sem exportar para gradle e funciona, também é necessário adicionar o caminho do ndk em local.properties , se mostrar erro, adicionar

sourceSets.main {
        jniLibs.srcDir 'src/main/libs' 
        jni.srcDirs = [] //disable automatic ndk-build callenter code here
    }

no arquivo build.gradle , crie a pasta e o arquivo jni usando o terminal e execute-o.


1
Veja veja minha própria resposta. Essa é a solução alternativa que estou usando atualmente, mas não é realmente uma solução.
plaisthos

1

Agora que o Android Studio está no canal estável, é bastante simples executar as amostras do Android-ndk . Essas amostras usam o plug-in experimental ndk e são mais recentes do que as vinculadas na documentação online do Android NDK. Depois de saber que eles funcionam, você pode estudar os arquivos build.gradle, local.properties e gradle-wrapper.properties e modificar seu projeto de acordo. A seguir estão as etapas para fazê-los funcionar.

  1. Vá para configurações, Aparência e comportamento, Configurações do sistema, SDK do Android, selecione a guia Ferramentas do SDK e verifique a versão 1.0.0 do Android NDK na parte inferior da lista. Isso fará o download do NDK.

  2. Aponte para o local do NDK recém-baixado. Observe que ele será colocado no diretório sdk / ndk-bundle. Faça isso selecionando Arquivo, Estrutura do projeto, Local do SDK (à esquerda) e fornecendo um caminho no local Android NDK. Isso adicionará uma entrada ndk ao local.properties semelhante a este:

    Mac / Linux: ndk.dir = / Android / sdk / ndk-bundle
    Windows: ndk.dir = C: \ Android \ sdk \ ndk-bundle

Eu construí e implantei com êxito todos os projetos no repositório dessa maneira, exceto gles3gni, codec nativo e construtor. Estou usando o seguinte:

Android Studio 1.3 build AI-141.2117773
amostras de android-ndk publicadas em 28 de julho de 2015 (link acima)
SDK Tools 24.3.3
NDK r10e extraído para C: \ Android \ sdk \ ndk-bundle
Gradle 2.5
Plug-in Gradle 0.2.0
Windows 8.1 64 bits


1

NDK Builds and gradle (basic)

Geralmente, criar com o NDK é tão simples quanto especificar corretamente um caminho ndkBuild para Android.mk ou um caminho cmake para CMakeLists.txt. Eu recomendo o CMake sobre o Android.mk antigo, porque o suporte a C / C ++ do Android Studio é baseado no CLion e usa o CMake como formato de projeto. Na minha experiência, isso tendeu a tornar o IDE mais responsivo em projetos maiores. Tudo o que é compilado no seu projeto será criado e copiado no APK automaticamente.

apply plugin: 'com.android.library'

android {
    compileSdkVersion 19
    buildToolsVersion "25.0.2"

    defaultConfig {
        minSdkVersion 19
        targetSdkVersion 19

        ndk {
            abiFilters 'armeabi', 'armeabi-v7a', 'x86'
            // 64-bit support requires an Android API level higher than 19; Namely 21 and higher
            //abiFilters 'armeabi', 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
        }

        externalNativeBuild {
            cmake {
                arguments '-DANDROID_TOOLCHAIN=clang',
                        '-DANDROID_PLATFORM=android-19',
                        '-DANDROID_STL=gnustl_static',
                        '-DANDROID_ARM_NEON=TRUE'

            }
        }
    }

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

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
}

Adicionando bibliotecas pré-construídas ao projeto (avançado)

As bibliotecas estáticas (.a) na sua compilação NDK serão automaticamente incluídas, mas as bibliotecas dinâmicas pré-criadas (.so) precisarão ser colocadas jniLibs. Isso pode ser configurado usando sourceSets, mas você deve adotar o padrão. Você NÃO PRECISA de nenhum comando adicional nobuild.gradle ao incluir bibliotecas pré-construídas.

O layout de jniLibs

Você pode encontrar mais informações sobre a estrutura no Guia do usuário do Android Gradle Plugin .

|--app:
|--|--build.gradle
|--|--src:
|--|--|--main
|--|--|--|--java
|--|--|--|--jni
|--|--|--|--|--CMakeLists.txt
|--|--|--|--jniLibs
|--|--|--|--|--armeabi
|--|--|--|--|--|--.so Files
|--|--|--|--|--armeabi-v7a
|--|--|--|--|--|--.so Files
|--|--|--|--|--x86
|--|--|--|--|--|--.so Files

Em seguida, você pode validar que o APK resultante contém seus arquivos .so, normalmente em build/outputs/apk/, usandounzip -l myApp.apk para listar o conteúdo.

Construindo bibliotecas compartilhadas

Se você estiver criando uma biblioteca compartilhada no NDK, não precisará fazer mais nada. Ele será agrupado corretamente no APK.


0

Basta adicionar essas linhas ao aplicativo build.gradle

dependencies {
    ...
    compile fileTree(dir: "$buildDir/native-libs", include: 'native-libs.jar')
}

task nativeLibsToJar(type: Zip, description: 'create a jar archive of the native libs') {
    destinationDir file("$buildDir/native-libs")
    baseName 'native-libs'
    extension 'jar'
    from fileTree(dir: 'libs', include: '**/*.so')
    into 'lib/armeabi/'
}

tasks.withType(JavaCompile) {
    compileTask -> compileTask.dependsOn(nativeLibsToJar)
}

Eu acho que a abordagem jniLibs.srcDirs é mais limpa do que isso, já que você pode usar abiFilter / flavors, mas sua abordagem também deve funcionar.
plaisthos 31/07

0

now.I pode carregar o tão sucesso!

1. adicione o arquivo .so a este caminho

Project:

| --src | - | --main | - | - | --java | - | - | --jniLibs | - | - | - | --armeabi | - | - Arquivos | - | - | -. so

2. adicione este código ao gradle.build

android {
splits {
    abi {
        enable true
        reset()
        include 'x86', 'x86_64', 'arm64-v8a', 'armeabi-v7a', 'armeabi'
        universalApk false
    }
}

}

3)System.loadLibrary("yousoname");

  1. boa sorte para você, está tudo bem com gradle 1.2.3

0
  1. Se seu projeto foi exportado do eclipse, adicione os códigos abaixo no arquivo gradle:

    android {
       sourceSets{
            main{
               jniLibs.srcDir['libs']  
          }  
        }
    }

2.Se você criar um projeto no Android studio:

crie uma pasta chamada jniLibs em src / main / , e coloque seus arquivos * .so na pasta jniLibs.

E copie o código como abaixo em seu arquivo gradle:

android {
    sourceSets{  
       main{  
         jniLibs.srcDir['jniLibs']  
      }  
    }
}

0

Embora eu acredite que SJoshi (oracle guy) tenha a resposta mais completa, o projeto SWIG é um caso especial, interessante e útil, mas não generalizado para a maioria dos projetos que se saíram bem com os projetos baseados em formigas SDK padrão + NDK. Todos nós gostaríamos de estar usando o Android studio agora, provavelmente, ou queremos uma cadeia de ferramentas de construção mais amigável para o IC para dispositivos móveis, que gradle oferece teoricamente.

Publiquei minha abordagem, emprestada de algum lugar (encontrei isso no SO, mas publiquei uma essência para o aplicativo build.gradle: https://gist.github.com/truedat101/c45ff2b69e91d5c8e9c7962d4b96e841 ). Em poucas palavras, recomendo o seguinte:

  • Não atualize seu projeto para a versão mais recente do gradle
  • Use com.android.tools.build:gradle:1.5.0 na raiz do projeto
  • Use com.android.application no seu projeto de aplicativo
  • Verifique se o gradle.properties possui: android.useDeprecatedNdk = true (caso esteja reclamando)
  • Use a abordagem acima para garantir que suas horas e horas de esforço na criação de arquivos Android.mk não sejam descartadas. Você controla quais alvos são construídos. E essas instruções são gentis com os usuários do Windows, que teoricamente devem poder construir no Windows sem problemas especiais.

Gradle para Android tem sido uma bagunça na minha opinião, por mais que eu goste dos conceitos emprestados e da estrutura de diretórios opinativa de um projeto. Esse recurso NDK está "chegando em breve" há quase três anos ou mais.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.