studio r16 ndk full developers descargar configurar android android-ndk gradle android-studio

r16 - Android studio, gradle y NDK



descargar android studio (23)

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 a ndk-build si tiene un directorio jni en las fuentes de su proyecto.

Esto está funcionando en Android studio 0.5.9 (canary build).

  1. Descargue el NDK
  2. Agregue ANDROID_NDK_HOME a las variables de entorno o agregue ndk.dir=/path/to/ndk a su local.properties en 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 de ndk. (Están en la parte inferior de la página). Un buen proyecto de muestra es ndkJniLib .
  4. Copie el gradle.build de los proyectos de muestra NDK. Se verá algo como esto. Este gradle.build crea una apk diferente para cada arquitectura. Debe seleccionar qué arquitectura desea utilizando el panel de build variants .

    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 manualmente el directorio para las fuentes 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 }

Además, es probable que desee llamar a ndk-build en su secuencia de comandos de compilación gradle de forma explícita, 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 }

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

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

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


NDK Builds y gradle (básico)

En general, compilar con el NDK es tan simple como especificar correctamente una ruta de acceso de ndkBuild a Android.mk o cmake a CMakeLists.txt. Recomiendo CMake sobre Android.mk anterior porque la compatibilidad 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á automáticamente en el 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'']) }

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 precompiladas (.so) deberán colocarse en jniLibs . Esto se puede configurar usando los conjuntos de sourceSets , pero debe adoptar el estándar. NO NECESITA ningún comando adicional en build.gradle al incluir bibliotecas build.gradle .

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 que la APK resultante contenga sus archivos .so, generalmente en build/outputs/apk/ , usando unzip -l myApp.apk para listar 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.


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

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

2.Si creas un proyecto en un estudio de Android:

crea una carpeta llamada jniLibs en src / main /, y coloca tus archivos * .so en la carpeta jniLibs.

Y copie el código como se muestra a continuación en su archivo gradle:

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


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

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

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

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

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

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

  6. Consulte el ejemplo de Código de Activity continuación para ver un ejemplo de cómo llamar a un método (¿o es una función?) En 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).


Ahora que Android Studio se encuentra en el canal estable, es bastante sencillo ejecutar las muestras de android-ndk . Estas muestras usan el plugin ndk experimental y son más nuevas 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 la configuración, Apariencia y comportamiento, Configuración del sistema, Android SDK, seleccione la pestaña Herramientas del SDK y compruebe Android NDK versión 1.0.0 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 de Android NDK. 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 construido e implementado con éxito todos los proyectos en el repositorio de esta manera, excepto gles3gni, native-codec y builder. 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 de 64 bits


Aunque creo que SJoshi (chico del oráculo) 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 basados ​​en antigüedades SDK estándar + NDK. A todos nos gustaría ahora usar el estudio de Android, o queremos una cadena de herramientas de construcción más amigable para CI para dispositivos móviles, que teóricamente ofrece Gradle.

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

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

Gradle para Android ha sido un desastre en mi opinión, tanto como me gustan los conceptos maven prestados y la estructura obstinada de directorios para un proyecto. Esta función NDK ha estado "próximamente" durante casi 3 años o más.



Con la actualización de Android Studio a 1.0, la compatibilidad con la herramienta NDK mejoró enormemente ( nota: lea mis actualizaciones en la parte inferior de esta publicación para ver el uso con el nuevo plugin Gradle experimental y Android Studio 1.5 ).

Android Studio y NDK están lo suficientemente integrados para que solo necesite crear un bloque ndk {} en build.gradle de su módulo, y establecer sus archivos fuente en el directorio (module) / src / main / jni, y usted está ¡hecho!

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

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

Los puntos destacados son:

Hay dos cosas que debes saber aquí. De forma predeterminada, si tiene librerías externas que desea cargar en la aplicación de Android, se buscan en (módulo) / src / main / jniLibs de forma predeterminada. Puede cambiar esto usando settingSets.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, brazo, mips, arm64-v8a, etc.)

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

y ponga esto en build.gradle de su 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 compilación de tu código C ++, desde allí necesitas cargarlo y crear contenedores, pero a juzgar por tu pregunta, ya sabes cómo hacer todo eso, así que no volveré a manipular.

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

ACTUALIZACIÓN: 14 de junio de 2015

Cuando sale Android Studio 1.3, debería haber un mejor soporte para C ++ a través del plugin JetBrains CLion. En este momento estoy suponiendo que esto permitirá el desarrollo de Java y C ++ desde Android Studio; sin embargo, creo que todavía tendremos que usar la sección de Gradle NDK como mencioné anteriormente. Además, creo que todavía habrá necesidad de escribir los archivos contenedores Java <-> C ++, a menos que CLion los haga automáticamente.

ACTUALIZACIÓN: 5 de enero de 2016

He actualizado mi blog y Repo Github (en la rama de desarrollo) para usar Android Studio 1.5 con el último plugin 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 construcció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 asombrosamente, Android Studio ha completado automáticamente para C ++ - envoltorios generados de Java usando la palabra clave ''native'':

Sin embargo, no es completamente color de rosa ... Si está utilizando SWIG para envolver una biblioteca para autogenerar código, y luego tratar de usar la generación automática de palabras clave nativas, colocará el código en el lugar equivocado en su Swig _wrap archivo .cxx ... Entonces debes moverlo al bloque "extern C":

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 creas un nuevo proyecto, simplemente selecciona la compatibilidad con C ++ y listo.

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

Los cambios en el archivo CMakeLists (que es donde coloca sus archivos fuente C ++) serán recogidos por Android Studio y automáticamente volverá a compilar cualquier biblioteca asociada.


Descubrí que "gradle 1.11 com.android.tools.build:gradle:0.9.+" ahora admite ndk preconstruido, solo puede poner * .so en dir src / main / jniLibs. cuando construyas gradle empaquetarás el ndk en el lugar correcto.

aquí está mi proyecto

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


Este es el código que uso para compilar usando android-ndk de gradle. Para esto agregue la ruta del directorio gradle.properties en gradle.properties es decir. agregue ndkdir=/home/user/android-ndk-r9d y coloque todos los archivos jni en una carpeta native en src/main/ como puede ver en el código publicado a continuación. Creará jar con libs nativas que puede usar normalmente como en System.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''


Estos son los pasos que utilicé para que funcione el NDK en mi proyecto de Android Studio. Utilicé 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, debajo de tu sdk.dir agrega

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 quieres darle a tu código nativo. Creo que esto es lo que 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 Eclipse NDK. ( http://www.kandroid.org/ndk/docs/CPLUSPLUS-SUPPORT.html )

cLas banderas son todavía 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 todo lo que necesite, ahí es donde lo encontré. Sé que el c ++ 11 me permite usar el nuevo estándar c ++ 11.

Aquí hay un ejemplo de cómo me conecto a 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());


He usado ndk.dir=/usr/shareData/android-ndk-r11b // ruta de acceso de ndk

en el archivo local.properties en el proyecto android studio. y agrega esta línea:
android.useDeprecatedNdk=true

en gradle.properties file en el proyecto android studio.

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


He utilizado 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) }



La respuesta de @plaisthos se rompió en la última versión gradle, pero todavía hay una manera de hacerlo. Cree un directorio native-libs en la raíz de su directorio de proyecto y copie todas las 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''


Para ampliar lo que Naxos dijo (¡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 Android Gradle plugin 0.7

Esta publicación contiene todos los detalles sobre cómo vincular las bibliotecas nativas pre compiladas 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, no debería necesitar hacer el trabajo alrededor de zip y copiar más.



Si está en Unix, la última versión (0.8) agrega ndk-build. A continuación, le mostramos 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 se rompe en Windows, debe deshabilitar la compilación con:

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


Solo agrega 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) }


Una buena respuesta para automatizar el empaquetado de .so -files fácilmente compilados se da en otro hilo (cerrado) . Para que 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, no se encontraron los archivos .so y, por lo tanto, la tarea de empaquetarlos nunca se ejecutará.


ahora. ¡Puedo cargar el éxito!

1.añadir el archivo .so a esta ruta

Project:

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

2.añadir 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

configurar proyecto en android studio desde eclipse: tienes que importar el proyecto eclipse ndk a android studio sin exportarlo a gradle y funciona, también necesitas agregar la ruta de acceso de ndk en local.properties , si muestra un error, luego agrega

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

en el archivo build.gradle luego crea la carpeta jni y el archivo usando terminal y ejecutarlo funcionará


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

Para compilar con un script, la siguiente solución de gradle debería funcionar:

Estoy usando mi script de compilación y agregado a mi archivo (Parece que funciona para 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 } } }

La compilación desafortunadamente no falla si el directorio no está presente o no contiene archivos .so .