Studio Android, livello e NDK


153

Sono molto nuovo di tutto questo supporto e supporto per Android Studio. Sono riuscito a convertire il mio progetto Android in gradle utilizzando l'opzione di esportazione.

Ma sto cercando un po 'di documentazione o punto di partenza su come integrare la build NDK nel processo di build gradle.

Se possibile, ho anche bisogno di una sorta di fase "after" che copi i binari di compilazione (file .so) nella directory degli asset.


Ho pubblicato la mia risposta nel link sotto indicato stackoverflow.com/questions/20900814/…
Ahmad Ali Nasir

24
Nuovi lettori: tenere presente che questa domanda è stata inizialmente posta durante il periodo beta di Android Studio; la risposta è cambiata nel tempo. Prestare attenzione alla versione Gradle menzionata nelle risposte, nonché quando le risposte sono state effettivamente pubblicate.
Sean Beach,

Se qualcosa cambia davvero, modificherò la domanda per riferire lo stato
plaisthos,

Android Studio 1.3 sul canale canarino supporta pienamente NDK. Riferimento: tools.android.com/download/studio/canary/latest
Vikasdeep Singh

18 giugno 2015: Android Studio 1.3 Beta è ora disponibile nel canale beta! Spiacenti, questa build non contiene ancora il supporto C / C ++; fonte: tools.android.com/recent/androidstudio13betaavailable
fastr.de

Risposte:


85

Abbiamo rilasciato una prima versione dell'integrazione come anteprima in 1.3: http://tools.android.com/tech-docs/android-ndk-preview

L'integrazione rimarrà un'anteprima anche dopo la 1.3 diventa definitiva. Nessun ETA corrente su quando sarà definitivo (al 2015/07/10).

Maggiori informazioni qui: http://tools.android.com/tech-docs/android-ndk-preview


2
Sarebbe bello se potessi usare NDK e completare il comando con il debug in Android Studio (e supporto Gradle)
powder366

1
@GREnvoy - Come possiamo configurare il giusto costruttore NDK in Android Studio? Puoi darmi i passaggi? :)
Shravan,

7
@DirtyBeach Perché è obsoleto? Non esiste ancora un'integrazione di NDK in Studio. Ci stiamo lavorando, ma non ci sono ETA in questo momento.
Xavier Ducrohet,

2
La mia azione si basava su come stavo definendo "integrazione". Ho capito che significa "un modo di usare l'NDK con gradle" che ora esiste, sebbene nessuna di esse sia una soluzione fantastica. Tuttavia, in base al tuo commento, sembra che il tuo team abbia qualcos'altro in mente per quello che potrebbe essere una vera integrazione. Ritiro la mia precedente dichiarazione.
Sean Beach,

2
L'integrazione NDK è stata annunciata durante Google IO 2015. È disponibile in Android Studio 1.3 (l'anteprima può essere scaricata a breve. Pubblica un link quando sarà disponibile).
Cypress Frankenfeld,

43

AGGIORNAMENTO: Android Studio con supporto NDK è ora disponibile: http://tools.android.com/tech-docs/android-ndk-preview

Per costruire con uno script la seguente soluzione gradle dovrebbe funzionare:

Sto usando il mio script di build e aggiunto al mio file (sembra funzionare 0.8+): questo sembra essere equivalente alla soluzione di seguito (ma sembra più bello nel file gradle):

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

La build purtroppo non fallisce se la directory non è presente o non contiene .sofile.


5
Questo non funziona più con la nuova versione di Android Studio, soluzione alternativa?
powder366

@ powder366 Vedi la mia risposta.
Leandros,

2
Un po 'di magia Groovy: tasks.withType(com.android.build.gradle.tasks.PackageApplication) { it.jniFolders = [file("libs")] as Set }. Grazie ragazzi per l'aiuto!
trnl

Qual è la procedura per Android Studio 0.8.9
Pandiri Deepak,

1
@plaisthos Grazie mille per aver indicato la giusta direzione! La seconda riga dello script Gradle jni.srcDirs = [] //disable automatic ndk-buildè molto importante poiché impedirà ad Android Studio di ricostruire il codice sorgente C / C ++. Ho cercato di capirlo per due giorni fino a quando ho visto il tuo post e questo ha risolto il mio problema. Penso davvero che NDK build sia meglio creato separatamente dal makefile della riga di comando di Android.mk, non dallo script gradle poiché C / C ++ è stato creato da Makefile da oltre 40 anni!
tonga,

40

Con l'aggiornamento di Android Studio alla 1.0, il supporto della toolchain NDK è migliorato immensamente ( nota: leggi i miei aggiornamenti in fondo a questo post per vedere l'utilizzo con il nuovo plug-in sperimentale Gradle e Android Studio 1.5 ).

Android Studio e NDK sono integrati abbastanza bene, quindi è sufficiente creare un blocco ndk {} nel build.gradle del modulo e impostare i file di origine nella directory (module) / src / main / jni - e tu sei fatto!

Non più ndk-build dalla riga di comando.

Ho scritto tutto al riguardo nel mio post sul blog qui: http://www.sureshjoshi.com/mobile/android-ndk-in-android-studio-with-swig/

I punti salienti sono:

Ci sono due cose che devi sapere qui. Per impostazione predefinita, se si dispone di librerie esterne che si desidera caricare nell'applicazione Android, vengono cercate in (modulo) / src / main / jniLibs per impostazione predefinita. Puoi cambiarlo impostando sourceSets.main.jniLibs.srcDirs in build.gradle del tuo modulo. Avrai bisogno di una sottodirectory con librerie per ogni architettura che stai prendendo di mira (ad es. X86, arm, mips, arm64-v8a, ecc ...)

Il codice che si desidera compilare per impostazione predefinita dalla toolchain NDK si troverà in (module) / src / main / jni e in modo simile sopra, è possibile modificarlo impostando sourceSets.main.jni.srcDirs nel build.gradle del modulo

e inseriscilo nel build.gradle del tuo modulo:

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
}

Questo è il processo di compilazione del codice C ++, da lì è necessario caricarlo e creare wrapper - ma a giudicare dalla tua domanda, sai già come fare tutto ciò, quindi non ricomincerò.

Inoltre, ho inserito un repository Github di questo esempio qui: http://github.com/sureshjoshi/android-ndk-swig-example

AGGIORNAMENTO: 14 giugno 2015

Quando esce Android Studio 1.3, dovrebbe esserci un miglior supporto per C ++ tramite il plug-in CLion JetBrains. Attualmente suppongo che ciò consentirà lo sviluppo di Java e C ++ da Android Studio; comunque penso che dovremo ancora usare la sezione Gradle NDK come ho detto sopra. Inoltre, penso che ci sarà ancora la necessità di scrivere i file wrapper Java <-> C ++, a meno che CLion non li esegua automaticamente.

AGGIORNAMENTO: 5 gennaio 2016

Ho aggiornato il mio blog e repository Github (nel ramo di sviluppo) per utilizzare Android Studio 1.5 con l'ultimo plug-in sperimentale 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

La build Gradle per la sezione NDK ora appare così:

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
}

Inoltre, abbastanza sorprendentemente, Android Studio ha il completamento automatico per C ++ - wrapper generati da Java usando la parola chiave "nativa":

Esempio di completamento automatico di C ++ - wrapper Java

Tuttavia, non è completamente roseo ... Se stai usando SWIG per avvolgere una libreria per generare automaticamente il codice, e quindi provare a usare la generazione automatica della parola chiave nativa, metterà il codice nella posizione sbagliata nel tuo Swig _wrap .cxx file ... Quindi è necessario spostarlo nel blocco "extern C":

C ++: wrapper Java spostato nella posizione corretta

AGGIORNAMENTO: 15 ottobre 2017

Sarei remissivo se non avessi menzionato che Android Studio 2.2 in poi ha essenzialmente il supporto "nativo" (senza giochi di parole) per la toolchain NDK tramite Gradle e CMake. Ora, quando crei un nuovo progetto, seleziona il supporto C ++ e sei a posto.

Sarà comunque necessario generare il proprio codice layer JNI o ​​utilizzare la tecnica SWIG che ho menzionato sopra, ma le impalcature di un C ++ in un progetto Android ora sono banali.

Le modifiche nel file CMakeLists (che è dove si posizionano i file sorgente C ++) verranno rilevate da Android Studio e ricompileranno automaticamente tutte le librerie associate.


1
mettere i * .so in (modulo) / src / main / jniLibs
Fawkes

perché NDEBUG è sempre impostato quando si utilizza Android Studio, anche su build di debug
pt123,

35

In Google IO 2015, Google ha annunciato la completa integrazione NDK in Android Studio 1.3.

Ora è fuori anteprima e disponibile per tutti: https://developer.android.com/studio/projects/add-native-code.html

Vecchia risposta: Gradle chiama automaticamente ndk-buildse si dispone di una jnidirectory nelle origini del progetto.

Funziona su Android Studio 0.5.9 (canary build).

  1. Scarica l'NDK

  2. Aggiungi ANDROID_NDK_HOMEalle variabili di ambiente o aggiungi ndk.dir=/path/to/ndkal tuo local.propertiesnel tuo progetto Android Studio. Ciò consente ad Android Studio di eseguire automaticamente ndk.

  3. Scarica gli ultimi progetti di esempio Gradle per vedere un esempio di un progetto ndk. (Sono in fondo alla pagina). Un buon progetto di esempio è ndkJniLib.

  4. Copia il gradle.builddai progetti di esempio NDK. Sembrerà qualcosa del genere. Questo gradle.buildcrea un apk diverso per ogni architettura. È necessario selezionare l'architettura desiderata utilizzando il build variantsriquadro. costruire il riquadro delle varianti

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

Nota che questo ignorerà i tuoi file Android.mk e Application.mk. Come soluzione alternativa, puoi dire a Gradle di disabilitare la chiamata atnomatic ndk-build, quindi specificare manualmente la directory per le fonti ndk.

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
}

Inoltre, probabilmente vorrai chiamare esplicitamente ndk-build nello script gradle build, perché hai appena disabilitato la chiamata automatica.

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

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

Sì. Ma questo funziona solo con piattaforme Unix e anche limitato se si tratta di una configurazione / makefile ndk più complessa rispetto a quella molto semplice.
plaisthos,

Sì, genererà automaticamente i makefile per le cose limitate che è possibile impostare nel file di build gradle, tuttavia esiste una soluzione alternativa. L'ho aggiunto alla mia risposta.
Cypress Frankenfeld,

1
La chiamata a ndk-build funzionerà solo dalla riga di comando e non da Android Studio.
Cameron Lowell Palmer,

Sebbene questa non sia la risposta più recente, sembra probabilmente la più accurata. Prestare particolare attenzione al passaggio 3: "Scarica gli ultimi progetti di esempio di laurea".
Sean Beach,

4
Uso questo hack invece di disabilitare dir src in modo da poter modificare i file c / c ++ all'interno tasks.all { task -> if (task.name.contains('Ndk')) task.enabled = false }
dell'ide

23

Ho trovato "gradle 1.11 com.android.tools.build:gradle:0.9.+" supporta pre-build ndk ora, puoi semplicemente mettere * .so nella directory src / main / jniLibs. quando si costruisce Gradle impacchetterà l'NK nel posto giusto.

ecco il mio progetto

Progetto:
| --src
| - | --main
| - | - | --java
| - | - | --jniLibs
| - | - | - | --armeabi
| - | - | - | - | -. so files
| --libs
| - | --other.jar


16

A partire da ora (Android Studio v0.8.6) è abbastanza semplice. Ecco i passaggi per creare un'app di tipo "Hello world":

  1. Scarica Android NDK e metti la cartella radice in qualche luogo sano di mente, forse nella stessa posizione della cartella SDK.

  2. Aggiungi quanto segue al tuo local.propertiesfile: ndk.dir=<path-to-ndk>

  3. Aggiungi quanto segue al tuo file build.gradle all'interno della defaultConfigchiusura, subito dopo la versionNameriga:ndk { moduleName="hello-world" }

  4. Nella maindirectory del modulo dell'app , crea una nuova cartella denominata jni.

  5. In quella cartella, crea un file chiamato hello-world.c, che vedrai di seguito.

  6. Vedi il Activitycodice di esempio di seguito per un esempio di come chiamare un metodo (o è una funzione?) In 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'])
}

Trova il codice sorgente completo di un'app molto simile qui (meno NDK).


Sto facendo esattamente come indicato nel mio progetto attuale, ma le cose NDK non vengono ancora costruite. Qualche idea? Sembra che stia costruendo tutto il resto, ma sta semplicemente saltando la roba jni.
alice.harrison,

@NannuoLei grazie, ho provato ma sto riscontrando un problema a causa del quale non viene generato il file .so. Tutto il resto sembra funzionare, ma quando eseguo apkg nell'emulatore, si lamenta che non è possibile caricare l'oggetto condiviso.
aaa90210,

@ aaa90210 il tuo emulatore si basa su un'immagine x86? Per impostazione predefinita, NDK produrrà solo una libreria ARMEABI, se vuoi creare un'immagine x86 puoi aggiungere questa riga in Application.mk: APP_ABI: = armeabi x86
Leo supporta Monica Cellio il

1
ha funzionato con me. PS: chiunque veda questa risposta, non dimenticare di cambiare il Java_me_mattlogan_ndktest_MainActivity_stringFromJNItuo :)
AbdulMomen عبدالمؤمن

8

Se sei su unix, l'ultima versione (0.8) aggiunge ndk-build. Ecco come aggiungerlo:

android.ndk {
    moduleName "libraw"
}

Si aspetta di trovare il JNI in 'src / main / jni', altrimenti puoi definirlo con:

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

A partire dal 28 gennaio 2014 con la versione 0.8 la build è interrotta su Windows, è necessario disabilitare la build con:

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

1
Esiste una documentazione per questa funzione? Non ne ho trovato nessuno. Al momento sembra che ignori completamente il mio Android.mk/Application.mk.
plaisthos,

Non ne ho trovato nessuno. Potrebbe essersi infiltrato nella build mezzo cotto. Sono su Windows, quindi posso solo confermare che non riesce a provare a chiamare lo script und ndk-build. Non ci sarebbero altri motivi per chiamarlo così per integrare la compilazione nativa in gradle. Sei in Unix?
Anthony,


in realtà si aspetta di trovare file * .so precompilati in jniLibs.srcDirs
Alpine

Non sarei d'accordo sulla base del fatto che si arresta in modo anomalo chiamando ndk-build che non è assolutamente necessario se richiede librerie compilate. Non posso confermare poiché non ho il tempo di vm Linux in questo momento.
Anthony,

7

Un'elegante soluzione alternativa è mostrata in https://groups.google.com/d/msg/adt-dev/nQobKd2Gl_8/Z5yWAvCh4h4J .

Fondamentalmente si crea un barattolo che contiene "lib / armeabi / yourlib.so" e quindi si include il barattolo nella build.


Si. Funziona bene solo se non si modifica spesso il codice nativo. E dovrai includere file jar binari nel repository. Altrimenti si finisce con uno script di build che crea un vaso al volo.
plaisthos,

1
Ho modificato l'esempio Hello-JNI di Android con un semplice script bash che avvolge ndk-build, genera .jars per ciascuno .soe li inserisce nel percorso di costruzione di Gradle per alleviare questo dolore. Controlla.
dbro,

4

Una buona risposta che automatizza il packaging di file compilati prontamente .soè data in un altro thread (chiuso) . Per farlo funzionare, ho dovuto cambiare linea:

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

in:

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

Senza questa modifica i .sofile non venivano trovati e l'attività di impacchettarli non sarebbe mai stata eseguita.


Aggiornamento: si noti che nei più recenti Android Studios (almeno nella versione 1.5) il codice nativo è molto meglio incorporato e non è necessario eseguire questa attività separata per impacchettare il codice.
HYS,

4

La risposta di @plaisthos si è rotta nell'ultima versione gradle, ma c'è ancora un modo per farlo. Crea una native-libsdirectory nella radice della directory del tuo progetto e copia tutte le nostre librerie in questa directory.

Aggiungi le seguenti righe al tuo build.gradle. Costruisci e sii felice.

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

Questo è il codice che uso per compilare usando android-ndk da Gradle. Per questo aggiungere il percorso della directory ndk in gradle.propertiesie. aggiungere ndkdir=/home/user/android-ndk-r9de mettere tutti i file in una cartella JNI nativea src/main/come si può vedere dal codice postato qui sotto. Creerà jar con librerie native che puoi usare normalmente come inSystem.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

Ho usato il seguente codice per compilare librerie dropbox native, sto usando 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

Per ampliare ciò che Naxos ha detto (Grazie Naxos per avermi inviato nella giusta direzione!), Ho imparato parecchio dagli esempi NDK rilasciati di recente e ho pubblicato una risposta in una domanda simile qui.

Come configurare NDK con il plug-in Android Gradle 0.7

Questo post contiene tutti i dettagli sul collegamento di librerie native predefinite nella tua app per le varie architetture, nonché informazioni su come aggiungere il supporto NDK direttamente allo script build.gradle. Per la maggior parte, non dovresti più dover lavorare su zip e copia.


1

Ecco i passaggi che ho usato per far funzionare l'NDK nel mio progetto Android Studio. Ho usato questo tutorial per aiutarmi https://software.intel.com/en-us/videos/using-the-ndk-with-android-studio

Per utilizzare NDK è necessario aggiungere una riga NDK a local.properties. Quindi sotto il tuo sdk.dir aggiungi

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

Nelle mie app build.gradle ho il seguente codice

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

moduleName è il nome che vuoi dare al tuo codice nativo. Credo che questo sarà il nome della libreria condivisa. ldLibs mi permette di accedere a LogCat, stl è lo stl che si desidera importare. Ci sono molte opzioni, come l'Eclipse NDK. ( http://www.kandroid.org/ndk/docs/CPLUSPLUS-SUPPORT.html )

Le bandiere sono ancora una certa quantità di magia nera per me. Non ho trovato una buona fonte per tutte le opzioni e ciò che mi danno. Cerca in StackOverflow tutto ciò di cui hai bisogno, ecco dove l'ho trovato. So che c ++ 11 mi permette di usare il nuovo standard c ++ 11.

Ecco un esempio di come accedo a LogCat dal codice 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

configura progetto in android studio da eclipse: devi importare il progetto eclipse ndk in android studio senza esportare in gradle e funziona, inoltre devi aggiungere il percorso di ndk in local.properties , se mostra errore quindi aggiungi

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

nel file build.gradle , quindi crea la cartella e il file jni usando il terminale ed esegui funzionerà


1
Vedi vedi la mia risposta. Questa è la soluzione alternativa che sto attualmente utilizzando, ma non è davvero una soluzione.
plaisthos,

1

Ora che Android Studio è nel canale stabile, è abbastanza semplice far funzionare i campioni android-ndk . Questi esempi utilizzano il plug-in sperimentale ndk e sono più recenti di quelli collegati alla documentazione online NDK di Android. Quando sai che funzionano, puoi studiare i file build.gradle, local.properties e gradle-wrapper.properties e modificare il tuo progetto di conseguenza. Di seguito sono riportati i passaggi per farli funzionare.

  1. Vai su Impostazioni, Aspetto e comportamento, Impostazioni di sistema, SDK Android, seleziona la scheda Strumenti SDK e controlla Android NDK versione 1.0.0 in fondo all'elenco. Questo scaricherà l'NDK.

  2. Indica la posizione dell'NDK appena scaricato. Si noti che verrà inserito nella directory sdk / ndk-bundle. A tale scopo, seleziona File, Struttura del progetto, Posizione SDK (a sinistra) e fornendo un percorso in Posizione NDK Android. Ciò aggiungerà una voce ndk a local.properties simile a questa:

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

Ho costruito e distribuito con successo tutti i progetti nel repository in questo modo, tranne gles3gni, native-codec e builder. Sto usando il seguente:

Android Studio 1.3 build AI-141.2117773
campioni android-ndk pubblicati il ​​28 luglio 2015 (link sopra)
Strumenti SDK 24.3.3
NDK r10e estratto in C: \ Android \ sdk \ ndk-bundle Grado
2.5 Plug-in Grado
0.2.0
Windows 8.1 64 bit


1

NDK Build e gradle (di base)

Generalmente costruire con NDK è semplice come specificare correttamente un percorso ndkBuild per Android.mk o un percorso cmake per CMakeLists.txt. Raccomando CMake su Android.mk precedente perché il supporto C / C ++ di Android Studio si basa su CLion e utilizza CMake come formato di progetto. Questo nella mia esperienza ha teso a rendere l'IDE più reattivo su progetti più grandi. Tutto ciò che è stato compilato nel progetto verrà creato e copiato automaticamente nell'APK.

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

Aggiunta di librerie predefinite al progetto (avanzato)

Le librerie statiche (.a) nella tua build NDK verranno automaticamente incluse, ma dovranno essere inserite librerie dinamiche precompilate (.so) jniLibs. Questo può essere configurato usando sourceSets, ma è necessario adottare lo standard. NON È NECESSARIO alcun comando aggiuntivo inbuild.gradle quando si includono librerie predefinite.

Il layout di jniLibs

Puoi trovare ulteriori informazioni sulla struttura nella Guida per l'utente del plug- in Android Gradle .

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

È quindi possibile convalidare l'APK risultante che contiene i file .so, in genere sotto build/outputs/apk/, utilizzando unzip -l myApp.apkper elencare i contenuti.

Costruire librerie condivise

Se stai costruendo una libreria condivisa nell'NDK non devi fare altro. Sarà correttamente raggruppato nell'APK.


0

Aggiungi queste righe all'app 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)
}

Penso che l'approccio jniLibs.srcDirs sia più pulito di così poiché puoi usare abiFilter / flavours ma il tuo approccio dovrebbe anche funzionare.
plaisthos,

0

ora. Posso caricare così tanto successo!

1.aggiungere il file .so a questo percorso

Project:

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

2.aggiungere questo codice a gradle.build

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

}

3.System.loadLibrary("yousoname");

  1. buona fortuna per te, va bene con il grado 1.2.3

0
  1. Se il tuo progetto è stato esportato da Eclipse, aggiungi i seguenti codici nel file gradle :

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

2.Se crei un progetto in Android Studio:

creare una cartella denominata jniLibs in src / main / , e inserire i file * .so nella cartella jniLibs.

E copia il codice come sotto nel tuo file gradle :

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

0

Mentre credo che SJoshi (oracle guy) abbia la risposta più completa, il progetto SWIG è un caso speciale, interessante e utile, ma non generalizzato per la maggior parte dei progetti che hanno funzionato bene con i progetti standard basati su formiche SDK + NDK. Tutti vorremmo usare Android Studio ora molto probabilmente, o desiderare una toolchain di build più compatibile con CI per dispositivi mobili, che il livello offre teoricamente.

Ho pubblicato il mio approccio, preso in prestito da qualche parte (l'ho trovato su SO, ma ho pubblicato un'essenza dell'app build.gradle: https://gist.github.com/truedat101/c45ff2b69e91d5c8e9c7962d4b96e841 ). In breve, raccomando quanto segue:

  • Non aggiornare il tuo progetto all'ultima build gradle
  • Utilizzare com.android.tools.build:gradle:1.5.0 nella radice del progetto
  • Usa com.android.application nel tuo progetto di app
  • Assicurati che gradle.properties abbia: android.useDeprecatedNdk = true (nel caso si stia lamentando)
  • Utilizza l'approccio sopra indicato per assicurarti che le tue ore e ore di lavoro nella creazione di file Android.mk non vengano eliminate. Tu controlli quali bersagli gli archi devono costruire. E queste istruzioni sono gentili per gli utenti Windows, che teoricamente dovrebbero essere in grado di costruire su Windows senza problemi speciali.

Gradle per Android è stato un disastro secondo me, tanto quanto mi piacciono i concetti di maven presi in prestito e la struttura supponente delle directory per un progetto. Questa funzionalità NDK è "in arrivo" da quasi 3+ anni.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.