Android studio, gradle y NDK


153

Soy muy nuevo en todo este soporte de gradle y Android Studio. He logrado convertir mi proyecto de Android a gradle usando la opción de exportación.

Pero estoy buscando documentación o punto de inicio sobre cómo integrar la compilación NDK en el proceso de compilación de Gradle.

Si es posible, también necesito algún tipo de etapa "posterior" que copie los archivos binarios de compilación (archivos .so) en el directorio de activos.


He publicado mi respuesta en el enlace mencionado a continuación stackoverflow.com/questions/20900814/…
Ahmad Ali Nasir

24
Nuevos lectores: Tenga en cuenta que esta pregunta se hizo inicialmente durante el período beta de Android Studio; La respuesta ha cambiado con el tiempo. Presta atención a la versión de Gradle mencionada en las respuestas, así como también cuando las respuestas fueron publicadas.
Sean Beach

Si algo realmente cambia
editaré

Android Studio 1.3 en el canal canario es totalmente compatible con NDK. Referencia: tools.android.com/download/studio/canary/latest
Vikasdeep Singh

18 de junio de 2015: ¡Android Studio 1.3 Beta ya está disponible en el canal beta! Lo sentimos, esta compilación aún no contiene el soporte C / C ++; fuente: tools.android.com/recent/androidstudio13betaavailable
fastr.de

Respuestas:


85

Hemos lanzado una primera versión de la integración como vista previa en 1.3: http://tools.android.com/tech-docs/android-ndk-preview

La integración seguirá siendo una vista previa incluso después de que 1.3 sea final. No hay una ETA actual sobre cuándo será final (a partir del 10/07/2015).

Más información aquí: http://tools.android.com/tech-docs/android-ndk-preview


2
Sería genial si pudiera usar NDK y completar el comando con la depuración en Android Studio (y soporte de Gradle)
powder366 19/12/2013

1
@GREnvoy: ¿cómo configuramos el generador de NDK correcto en el estudio de Android? ¿Me puede dar los pasos? :)
Shravan

77
@DirtyBeach ¿Por qué está desactualizado? Todavía no hay una integración del NDK en Studio. Estamos trabajando en ello, pero no hay ETA en este momento.
Xavier Ducrohet

2
Mi acción se basó en cómo estaba definiendo la "integración". Entendí que significaba "una forma de usar el NDK con gradle" que ahora existe, aunque ninguna de ellas son soluciones fantásticas. Sin embargo, según su comentario, parece que su equipo tiene algo más en mente sobre lo que podría ser una verdadera integración. Retracto mi declaración anterior.
Sean Beach

2
La integración de NDK se anunció durante Google IO 2015. Está disponible en Android Studio 1.3 (la vista previa se puede descargar pronto. Publicaré un enlace cuando esté disponible).
Cypress Frankenfeld

43

ACTUALIZACIÓN: Android Studio con soporte NDK ya está disponible: http://tools.android.com/tech-docs/android-ndk-preview

Para construir con un script, la solución de Gradle a continuación debería funcionar:

Estoy usando mi script de compilación y lo agregué a mi archivo (parece funcionar 0.8+): esto parece ser equivalente a la solución a continuación (pero se ve mejor en el archivo gradle):

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

Desafortunadamente, la compilación no falla si el directorio no está presente o no contiene .soarchivos.


55
Esto ya no funciona con la nueva versión de Android Studio, ¿solución alternativa?
powder366

@ powder366 Mira mi respuesta.
Leandros

2
Un poco de magia maravillosa: tasks.withType(com.android.build.gradle.tasks.PackageApplication) { it.jniFolders = [file("libs")] as Set }. Gracias chicos por la ayuda!
trnl

¿Cuál es el procedimiento para Android Studio 0.8.9?
Pandiri Deepak

1
@plaisthos ¡Muchas gracias por señalar la dirección correcta! La segunda línea en el script gradle jni.srcDirs = [] //disable automatic ndk-buildes muy importante ya que evitará que Android Studio reconstruya el código fuente C / C ++. He estado tratando de resolver esto durante dos días hasta que vi tu publicación y esto resolvió mi problema. Realmente creo que la compilación de NDK se construye mejor por separado solo con el archivo MAKE de la línea de comandos de Android.mk, no con la secuencia de comandos Gradle, ya que Makefile ha creado C / C ++ durante más de 40 años.
tonga

40

Con la actualización de Android Studio a 1.0, el soporte de la cadena de herramientas NDK mejoró inmensamente ( nota: lea mis actualizaciones al final de esta publicación para ver el uso con el nuevo complemento experimental Gradle y Android Studio 1.5 ).

Android Studio y el NDK se integran lo suficientemente bien como para que solo necesite crear un bloque ndk {} en el build.gradle de su módulo y configurar sus archivos de origen en el directorio (module) / src / main / jni, y estará ¡hecho!

No más ndk-build desde la línea de comandos.

He escrito todo sobre esto en mi blog aquí: http://www.sureshjoshi.com/mobile/android-ndk-in-android-studio-with-swig/

Los puntos más destacados son:

Hay dos cosas que debes saber aquí. De forma predeterminada, si tiene bibliotecas externas que desea cargar en la aplicación de Android, se buscan en el (módulo) / src / main / jniLibs de forma predeterminada. Puede cambiar esto mediante la configuración de sourceSets.main.jniLibs.srcDirs en build.gradle de su módulo. Necesitará un subdirectorio con bibliotecas para cada arquitectura a la que se dirige (por ejemplo, x86, arm, mips, arm64-v8a, etc.)

El código que desea que la cadena de herramientas NDK compile de manera predeterminada se ubicará en (module) / src / main / jni y, de manera similar a lo anterior, puede cambiarlo configurando sourceSets.main.jni.srcDirs en build.gradle de su módulo

y pon esto en el build.gradle de tu 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
}

Ese es el proceso de compilar su código C ++, desde allí debe cargarlo y crear envoltorios, pero a juzgar por su pregunta, ya sabe cómo hacer todo eso, por lo que no volveré a hacer hash.

Además, he colocado un repositorio de Github de este ejemplo aquí: http://github.com/sureshjoshi/android-ndk-swig-example

ACTUALIZACIÓN: 14 de junio de 2015

Cuando salga Android Studio 1.3, debería haber un mejor soporte para C ++ a través del complemento JetBrains CLion. Actualmente estoy asumiendo que esto permitirá el desarrollo de Java y C ++ desde Android Studio; Sin embargo, creo que aún tendremos que usar la sección Gradle NDK como he dicho anteriormente. Además, creo que aún será necesario escribir archivos de envoltura Java <-> C ++, a menos que CLion los haga automáticamente.

ACTUALIZACIÓN: 5 de enero de 2016

He actualizado mi blog y el repositorio de Github (en la rama de desarrollo) para usar Android Studio 1.5 con el último complemento experimental de 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 compilación de Gradle para la sección NDK ahora se ve así:

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
}

Además, bastante asombroso, Android Studio tiene autocompletado para C ++: contenedores generados por Java usando la palabra clave 'nativa':

Ejemplo de autocompletar de C ++ - contenedor Java

Sin embargo, no es completamente color de rosa ... Si está utilizando SWIG para ajustar una biblioteca para generar automáticamente el código, y luego intenta usar la palabra clave nativa autogeneración, colocará el código en el lugar incorrecto en su Swig _wrap archivo .cxx ... Por lo tanto, debe moverlo al bloque "C externo":

C ++: el contenedor Java se movió a la ubicación correcta

ACTUALIZACIÓN: 15 de octubre de 2017

Sería negligente si no mencionara que Android Studio 2.2 en adelante tiene soporte esencialmente 'nativo' (sin juego de palabras) para la cadena de herramientas NDK a través de Gradle y CMake. Ahora, cuando cree un nuevo proyecto, simplemente seleccione el soporte de C ++ y estará listo.

Aún necesitará generar su propio código de capa JNI, o usar la técnica SWIG que he mencionado anteriormente, pero el andamiaje de un proyecto C ++ en Android es trivial ahora.

Android Studio recogerá los cambios en el archivo CMakeLists (que es donde coloca los archivos fuente de C ++) y volverá a compilar automáticamente las bibliotecas asociadas.


1
poner * .so en (módulo) / src / main / jniLibs
fawkes

¿por qué NDEBUG siempre se configura cuando se usa Android Studio, incluso en las versiones de depuración?
pt123

35

En Google IO 2015, Google anunció la integración completa de NDK en Android Studio 1.3.

Ahora está fuera de vista previa y está disponible para todos: https://developer.android.com/studio/projects/add-native-code.html

Respuesta anterior: Gradle llama automáticamente ndk-buildsi tiene un jnidirectorio en las fuentes de su proyecto.

Esto está funcionando en Android Studio 0.5.9 (construcción canaria).

  1. Descargar el NDK

  2. Agregue ANDROID_NDK_HOMEa sus variables de entorno o agregue ndk.dir=/path/to/ndka su local.propertiesen su proyecto de Android Studio. Esto permite que Android Studio ejecute el ndk automáticamente.

  3. Descargue los últimos proyectos de muestra de gradle para ver un ejemplo de un proyecto ndk. (Están al final de la página). Un buen proyecto de muestra es ndkJniLib.

  4. Copie los gradle.buildproyectos de muestra de NDK. Se verá más o menos así. Esto gradle.buildcrea un apk diferente para cada arquitectura. Debe seleccionar qué arquitectura desea usar con el build variantspanel. panel de variantes de construcción

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

Tenga en cuenta que esto ignorará sus archivos Android.mk y Application.mk. Como solución alternativa, puede indicarle a gradle que deshabilite la llamada atuomatic ndk-build, luego especifique el directorio para las fuentes 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
}

Además, es probable que desee llamar a ndk-build en su secuencia de comandos de construcción gradle explícitamente, porque acaba de deshabilitar la llamada automática.

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

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

Si. Pero eso solo funciona en plataformas Unix y también es limitado si tiene una configuración / makefiles ndk más compleja que muy simple.
plaisthos

Sí, generará automáticamente archivos MAKE para las cosas limitadas que puede establecer en el archivo de compilación de Gradle, sin embargo, hay una solución alternativa. Lo agregué a mi respuesta.
Cypress Frankenfeld

1
La llamada a ndk-build solo funcionará en la línea de comandos, no desde Android Studio.
Cameron Lowell Palmer el

Aunque esta no es la respuesta más reciente, parece probable que sea la más precisa. Preste especial atención al paso 3: "Descargue los últimos proyectos de muestra de gradle".
Sean Beach

44
Uso este truco en lugar de deshabilitar el directorio src para poder editar archivos c / c ++ dentro de idetasks.all { task -> if (task.name.contains('Ndk')) task.enabled = false }
sherpya el

23

Encontré que "gradle 1.11 com.android.tools.build:gradle:0.9.+" ahora admite ndk precompilación, solo puede poner * .so en el directorio src / main / jniLibs. al construir gradle, se empaquetará el ndk en el lugar correcto.

aqui esta mi proyecto

Proyecto:
| --src
| - | --principal
| - | - | --java
| - | - | --jniLibs
| - | - | - | --armeabi
| - | - | - | - | -. así archivos
| --libs
| - | --other.jar


16

A partir de ahora (Android Studio v0.8.6) es bastante simple. Estos son los pasos para crear una aplicación tipo "Hola mundo":

  1. Descargue el NDK de Android y coloque la carpeta raíz en algún lugar sano, tal vez en la misma ubicación que la carpeta SDK.

  2. Agregue lo siguiente a su local.propertiesarchivo: ndk.dir=<path-to-ndk>

  3. Agregue lo siguiente a su archivo build.gradle dentro del defaultConfigcierre, justo después de la versionNamelínea:ndk { moduleName="hello-world" }

  4. En el maindirectorio de su módulo de aplicación , cree una nueva carpeta llamada jni.

  5. En esa carpeta, cree un archivo llamado hello-world.c, que verá a continuación.

  6. Vea el Activitycódigo de ejemplo a continuación para obtener un ejemplo de cómo llamar a un método (¿o es una función?) 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'])
}

Encuentre el código fuente completo de una aplicación muy similar aquí (menos el NDK).


Estoy haciendo exactamente lo que se indica en mi proyecto actual, pero las cosas de NDK todavía no se están construyendo. ¿Algunas ideas? Parece que está construyendo todo lo demás, pero simplemente omitiendo las cosas jni.
alice.harrison

@NannuoLei gracias, lo intenté pero tengo un problema donde no se está generando el .so. Todo lo demás parece funcionar, pero cuando ejecuto el apkg en el emulador, se queja de que no puede cargar el objeto compartido.
aaa90210

@ aaa90210 ¿su emulador se basa en una imagen x86? Por defecto, NDK solo producirá una biblioteca ARMEABI, si desea construir una imagen x86 puede agregar esta línea en Application.mk: APP_ABI: = armeabi x86
Leo admite a Monica Cellio el

1
Funcionó conmigo. PD: cualquiera que vea esta respuesta, no olvide cambiar Java_me_mattlogan_ndktest_MainActivity_stringFromJNIla suya :)
AbdulMomen عبدالمؤمن

8

Si está en Unix, la última versión (0.8) agrega ndk-build. Aquí se explica cómo agregarlo:

android.ndk {
    moduleName "libraw"
}

Espera encontrar el JNI en 'src / main / jni', de lo contrario puede definirlo con:

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

A partir del 28 de enero de 2014 con la versión 0.8, la compilación está rota en Windows, debe deshabilitar la compilación con:

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

1
¿Hay alguna documentación para esa característica? No pude encontrar ninguno. Por el momento, parece ignorar por completo mi Android.mk/Application.mk.
plaisthos

No he encontrado ninguno. Es posible que se haya colado en la construcción a medio hornear. Estoy en Windows, así que solo puedo confirmar que falla al intentar llamar al script Unix ndk-build. No habría otra razón para llamar a eso para integrar la compilación nativa en gradle. ¿Estás en Unix?
Anthony


en realidad espera encontrar archivos * .so precompilados en jniLibs.srcDirs
Alpine

No estoy de acuerdo debido al hecho de que se bloquea al llamar a ndk-build, lo que no es absolutamente necesario si requiere bibliotecas compiladas. No puedo confirmar ya que no tengo tiempo para vm Linux en este momento.
Anthony

7

Se muestra una solución alternativa elegante en https://groups.google.com/d/msg/adt-dev/nQobKd2Gl_8/Z5yWAvCh4h4J .

Básicamente, crea un jar que contiene "lib / armeabi / yourlib.so" y luego incluye el jar en la compilación.


Si. Eso solo funciona bien si no cambia su código nativo con frecuencia. Y tendrá que incluir archivos jar binarios en el repositorio. De lo contrario, terminará con un script de compilación que crea un frasco en marcha.
plaisthos

1
He modificado ejemplo Hola en JNI de Android con una escritura del golpe sencillo que se envuelve ndk-build, genera .jars para cada uno .soy los coloca en la trayectoria de la estructura de Gradle para aliviar este dolor. Echale un vistazo.
dbro

4

Una buena respuesta que automatiza el empaquetado de .soarchivos fácilmente compilados se da en otro hilo (cerrado) . Para que eso funcione, tuve que cambiar la línea:

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

dentro:

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

Sin este cambio .so, no se encontraron los archivos y, por lo tanto, la tarea de empaquetarlos nunca se ejecutaría.


Actualización: tenga en cuenta que en los nuevos estudios de Android (al menos en 1.5) el código nativo está mucho mejor incorporado, y no es necesario hacer esta tarea por separado para empaquetar su código.
HYS

4

La respuesta de @plaisthos se rompió en la última versión de gradle, pero todavía hay una manera de hacerlo. Cree un native-libsdirectorio en la raíz del directorio de su proyecto y copie todas sus bibliotecas en este directorio.

Agregue las siguientes líneas a su build.gradle. Construye y sé 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 es el código que uso para construir usando android-ndk de gradle. Para esto, agregue la ruta del directorio ndk en gradle.propertiesie. añadir ndkdir=/home/user/android-ndk-r9dy poner todos los archivos en una carpeta JNI nativeen src/main/como se puede ver a partir del código publica a continuación. Creará jar con bibliotecas nativas que puede usar normalmente como enSystem.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

He usado el siguiente código para compilar bibliotecas nativas de Dropbox, estoy 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

Para ampliar lo que dijo Naxos (¡Gracias Naxos por enviarme en la dirección correcta!), Aprendí bastante de los ejemplos de NDK recientemente publicados y publiqué una respuesta en una pregunta similar aquí.

Cómo configurar NDK con el complemento Android Gradle 0.7

Esta publicación tiene detalles completos sobre cómo vincular bibliotecas nativas preconstruidas en su aplicación para las diversas arquitecturas, así como información sobre cómo agregar soporte NDK directamente al script build.gradle. En su mayor parte, ya no debería necesitar hacer el trabajo de comprimir y copiar.


1

Estos son los pasos que utilicé para que el NDK funcionara en mi proyecto de Android Studio. Usé este tutorial para ayudarme https://software.intel.com/en-us/videos/using-the-ndk-with-android-studio

Para usar NDK debe agregar una línea NDK a local.properties. Entonces, bajo su sdk.dir, agregue

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

En mis aplicaciones build.gradle tengo el siguiente código

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

moduleName es el nombre que desea darle a su código nativo. Creo que así se llamará la biblioteca compartida. ldLibs me permite iniciar sesión en LogCat, stl es el stl que desea importar. Hay muchas opciones, igual que el Eclipse NDK. ( http://www.kandroid.org/ndk/docs/CPLUSPLUS-SUPPORT.html )

c Las banderas siguen siendo una cierta cantidad de magia negra para mí. No he encontrado una buena fuente para todas las opciones y lo que me dan. Busque en StackOverflow cualquier cosa que necesite, ahí es donde la encontré. Sé que el c ++ 11 me permite usar el nuevo estándar c ++ 11.

Aquí hay un ejemplo de cómo inicio sesión en LogCat desde el 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

configure project en android studio desde eclipse: debe importar eclipse ndk project a android studio sin exportar a gradle y funciona, también necesita agregar la ruta de ndk en local.properties , si muestra un error, agregue

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

en el archivo build.gradle , luego cree la carpeta y el archivo jni usando la terminal y ejecútelo funcionará


1
Ver ver mi propia respuesta. Esa es la solución que estoy usando actualmente, pero en realidad no es una solución.
plaisthos

1

Ahora que Android Studio está en el canal estable, es bastante sencillo ejecutar las muestras de Android-NDK . Estas muestras usan el complemento experimental ndk y son más recientes que las vinculadas desde la documentación en línea de Android NDK. Una vez que sepa que funcionan, puede estudiar los archivos build.gradle, local.properties y gradle-wrapper.properties y modificar su proyecto en consecuencia. Los siguientes son los pasos para que funcionen.

  1. Vaya a configuración, Apariencia y comportamiento, Configuración del sistema, SDK de Android, seleccione la pestaña Herramientas del SDK y verifique la versión 1.0.0 de Android NDK en la parte inferior de la lista. Esto descargará el NDK.

  2. Señale la ubicación del NDK recién descargado. Tenga en cuenta que se colocará en el directorio sdk / ndk-bundle. Para ello, seleccione Archivo, Estructura del proyecto, Ubicación del SDK (a la izquierda) y proporcione una ruta en la ubicación del NDK de Android. Esto agregará una entrada ndk a local.properties similar a esto:

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

He creado e implementado con éxito todos los proyectos en el repositorio de esta manera, excepto gles3gni, codec nativo y generador. Estoy usando lo siguiente:

Android Studio 1.3 build AI-141.2117773
muestras de android-ndk publicadas el 28 de julio de 2015 (enlace de arriba)
SDK Tools 24.3.3
NDK r10e extraído a C: \ Android \ sdk \ ndk-bundle
Gradle 2.5
Gradle plugin 0.2.0
Windows 8.1 64 bit


1

NDK Builds y gradle (básico)

En general, construir con el NDK es tan simple como especificar correctamente una ruta ndkBuild a Android.mk o una ruta cmake a CMakeLists.txt. Recomiendo CMake sobre el anterior Android.mk porque el soporte C / C ++ de Android Studio se basa en CLion y utiliza CMake como formato de proyecto. Esto en mi experiencia ha tendido a hacer que el IDE sea más receptivo en proyectos más grandes. Todo lo compilado en su proyecto se compilará y copiará en el APK automáticamente.

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

Agregar bibliotecas precompiladas al proyecto (avanzado)

Las bibliotecas estáticas (.a) en su compilación NDK se incluirán automáticamente, pero las bibliotecas dinámicas preconstruidas (.so) deberán colocarse jniLibs. Esto se puede configurar usando sourceSets, pero debe adoptar el estándar. NO NECESITA ningún comando adicional build.gradleal incluir bibliotecas preconstruidas.

El diseño de jniLibs

Puede encontrar más información sobre la estructura en la Guía del usuario de Android Gradle Plugin .

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

A continuación, puede validar el APK resultante que contiene sus archivos .so, generalmente debajo build/outputs/apk/, usandounzip -l myApp.apk para enumerar los contenidos.

Construyendo bibliotecas compartidas

Si está creando una biblioteca compartida en el NDK, no necesita hacer nada más. Se incluirá correctamente en el APK.


0

Simplemente agregue estas líneas a la aplicación 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)
}

Creo que el enfoque jniLibs.srcDirs es más limpio que esto, ya que puede usar abiFilter / flavors, pero su enfoque también debería funcionar.
plaisthos

0

¡Ahora puedo cargar el éxito!

1.Agregue el archivo .so a esta ruta

Project:

| --src | - | --main | - | - | --java | - | - | --jniLibs | - | - | - | --armeabi | - | - | - | - | -. así archivos

2.agregue este código 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. buena suerte para ti, está bien con gradle 1.2.3

0
  1. Si su proyecto se exportó desde eclipse, agregue los siguientes códigos en el archivo gradle:

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

2. Si crea un proyecto en el estudio de Android:

cree una carpeta llamada jniLibs en src / main / , y coloque sus archivos * .so en la carpeta jniLibs.

Y copie el código de la siguiente manera en su archivo gradle:

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

0

Si bien creo que SJoshi (oracle guy) tiene la respuesta más completa, el proyecto SWIG es un caso especial, interesante y útil, pero no generalizado para la mayoría de los proyectos que han funcionado bien con los proyectos estándar basados ​​en hormigas SDK + NDK Es muy probable que todos estemos usando Android Studio ahora, o que deseemos una cadena de herramientas de compilación más amigable con CI para dispositivos móviles, que teóricamente ofrece Gradle.

Publiqué mi enfoque, tomé prestado de algún lugar (encontré esto en SO, pero publiqué una idea general de la aplicación build.gradle: https://gist.github.com/truedat101/c45ff2b69e91d5c8e9c7962d4b96e841 ). En pocas palabras, recomiendo lo siguiente:

  • No actualice su proyecto a la última versión gradle
  • Use com.android.tools.build:gradle:1.5.0 en la raíz de su proyecto
  • Use com.android.application en su proyecto de aplicación
  • Asegúrese de que gradle.properties tenga: android.useDeprecatedNdk = true (en caso de que se queje)
  • Utilice el enfoque anterior para asegurarse de que sus horas y horas de esfuerzo creando archivos Android.mk no se descartarán. Usted controla qué arco (s) de objetivos construir. Y estas instrucciones son amables para los usuarios de Windows, que en teoría deberían poder construir en Windows sin problemas especiales.

Gradle para Android ha sido un desastre en mi opinión, por mucho que me gusten los conceptos de Maven prestados y la estructura obvia de los directorios para un proyecto. Esta función NDK ha estado "próximamente" por más de 3 años.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.