¿Cómo incluir la biblioteca * .so en Android Studio?

Leí muchos hilos de cómo agregar una biblioteca * .so a Android Studio, pero ninguno de ellos funciona, especialmente cuando se trata del punto de texto: Esto no funciona con el xxx más nuevo (Android Studio, gradle, …)

¿Podemos hacer un nuevo comienzo por favor? Tengo:

Android Studio 0.6.0

Desde la estructura del proyecto veo:

Ubicación del SDK:

/usr/share/android-studio/data/sdk /usr/lib/jvm/default-java 

Proyecto:

 Gradle version 1.10 Android Plugin Version 0.11.+ 

Módulos / aplicación: Propiedades:

Compile Sdk Versión 19 Build Tools Versión 19.1.0

Dependencias:

 {dir=libs, include=[*.jar]} Compile {dir=libs, include=[*.so]} Provided m com.android.support: appcompat -v7:19.+ Compile 

Obtuve los archivos * .so precomstackdos y en la aplicación de demostración que están trabajando. Tengo que cambiar el código fuente de la aplicación, así que necesito reconstruir con los mismos archivos * .so.

Solución actual

Cree la carpeta project/app/src/main/jniLibs , y luego ponga sus archivos *.so dentro de sus carpetas abi en esa ubicación. P.ej,

 project/ ├──libs/ | └── *.jar <-- if your library has jar files, they go here ├──src/ └── main/ ├── AndroidManifest.xml ├── java/ └── jniLibs/ ├── arm64-v8a/ <-- ARM 64bit │ └── yourlib.so ├── armeabi-v7a/ <-- ARM 32bit │ └── yourlib.so └── x86/ <-- Intel 32bit └── yourlib.so 

Solución obsoleta

Agregue ambos fragmentos de código en su archivo gradle.build de módulo como una dependencia:

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

Cómo crear este jar personalizado

 task nativeLibsToJar(type: Jar, description: 'create a jar archive of the native libs') { destinationDir file("$buildDir/native-libs") baseName 'native-libs' from fileTree(dir: 'libs', include: '**/*.so') into 'lib/' } tasks.withType(JavaCompile) { compileTask -> compileTask.dependsOn(nativeLibsToJar) } 

La misma respuesta también se puede encontrar en una pregunta relacionada: Incluir la biblioteca .so en apk en android studio

Agregar .so Library en Android Studio 1.0.2

  1. Crear carpeta “jniLibs” dentro de “src / main /”
  2. Coloque todas sus bibliotecas .so dentro de la carpeta “src / main / jniLibs”
  3. La estructura de la carpeta parece,
    | –app:
    | – | –src:
    | – | – | –main
    | – | – | – | –jniLibs
    | – | – | – | – | –armeabi
    | – | – | – | – | – | -. so archivos
    | – | – | – | – | –x86
    | – | – | – | – | – | -. so archivos
  4. Ningún código adicional requiere simplemente sincronizar su proyecto y ejecutar su aplicación.

    Referencia
    https://github.com/commonsguy/sqlcipher-gradle/tree/master/src/main

* .so biblioteca en Android Studio

Tienes que generar la carpeta jniLibs dentro de main en los proyectos de Android Studio y poner todos tus archivos .so dentro. También puede integrar esta línea en build.gradle

comstackr fileTree (dir: ‘libs’, include: [‘ .jar’, ‘ .so’])

Funciona perfectamente

| –app:

| – | –src:

| – | – | –main

| – | – | – | –jniLibs

| – | – | – | – | –armeabi

| – | – | – | – | – | -. so archivos

Esta es la estructura del proyecto.

Solución 1: creación de una carpeta JniLibs

Crea una carpeta llamada “jniLibs” en tu aplicación y las carpetas que contienen tu * .so adentro. La carpeta “jniLibs” debe crearse en la misma carpeta que las carpetas “Java” o “Assets”.

Solución 2: modificación del archivo build.gradle

Si no desea crear una nueva carpeta y mantener sus archivos * .so en la carpeta libs, ¡es posible!

En ese caso, solo agregue sus archivos * .so en la carpeta libs (respete la misma architecture que la solución 1: libs / armeabi / .so por ejemplo) y modifique el archivo build.gradle de su aplicación para agregar el directorio fuente de los jniLibs.

 sourceSets { main { jniLibs.srcDirs = ["libs"] } } 

Tendrás más explicaciones, con capturas de pantalla para ayudarte aquí (Paso 6):

http://blog.guillaumeagis.eu/setup-andengine-with-android-studio/

EDITAR Tenía que ser jniLibs.srcDirs, no jni.srcDirs – editado el código. El directorio puede ser una ruta [relativa] que señala fuera del directorio del proyecto.

Este es mi archivo build.gradle, tenga en cuenta la línea

 jniLibs.srcDirs = ['libs'] 

Esto incluirá el archivo * .so de libs para apk.

 sourceSets { main { manifest.srcFile 'AndroidManifest.xml' java.srcDirs = ['src'] resources.srcDirs = ['src'] aidl.srcDirs = ['src'] renderscript.srcDirs = ['src'] res.srcDirs = ['res'] assets.srcDirs = ['assets'] jniLibs.srcDirs = ['libs'] } // Move the tests to tests/java, tests/res, etc... instrumentTest.setRoot('tests') // Move the build types to build-types/ // For instance, build-types/debug/java, build-types/debug/AndroidManifest.xml, ... // This moves them out of them default location under src//... which would // conflict with src/ being used by the main source set. // Adding new build types or product flavors should be accompanied // by a similar customization. debug.setRoot('build-types/debug') release.setRoot('build-types/release') } 

Para usar la biblioteca nativa (archivos so) Necesita agregar algunos códigos en el archivo “build.gradle”.

Este código es para limpiar el directorio “armeabi” y copiar archivos ‘so’ en “armeabi” mientras que ‘limpiar proyecto’.

 task copyJniLibs(type: Copy) { from 'libs/armeabi' into 'src/main/jniLibs/armeabi' } tasks.withType(JavaCompile) { compileTask -> compileTask.dependsOn(copyJniLibs) } clean.dependsOn 'cleanCopyJniLibs' 

Me han recomendado desde abajo. https://gist.github.com/pocmo/6461138

Android NDK oficial hello-libs CMake ejemplo

https://github.com/googlesamples/android-ndk/tree/840858984e1bb8a7fab37c1b7c571efbe7d6eb75/hello-libs

Acabo de trabajar para mí en el host Ubuntu 17.10, Android Studio 3, SDK 26 de Android, por lo que le recomiendo que base su proyecto en él.

La biblioteca compartida se llama libgperf , las partes del código clave son:

  • hello-libs / app / src / main / cpp / CMakeLists.txt :

     // -L add_library(lib_gperf SHARED IMPORTED) set_target_properties(lib_gperf PROPERTIES IMPORTED_LOCATION ${distribution_DIR}/gperf/lib/${ANDROID_ABI}/libgperf.so) // -I target_include_directories(hello-libs PRIVATE ${distribution_DIR}/gperf/include) // -lgperf target_link_libraries(hello-libs lib_gperf) 
  • app / build.gradle :

     android { sourceSets { main { // let gradle pack the shared library into apk jniLibs.srcDirs = ['../distribution/gperf/lib'] 

    Luego, si miras en /data/app en el dispositivo, libgperf.so estará allí también.

  • en código C ++, use: #include

  • Ubicación del encabezado: hello-libs/distribution/gperf/include/gperf.h

  • ubicación lib: distribution/gperf/lib/arm64-v8a/libgperf.so

  • Si solo admite algunas architectures, consulte: Gradle Build NDK target only ARM

El git de ejemplo rastrea las bibliotecas compartidas previamente comstackdas, pero también contiene el sistema de comstackción para construirlas también: https://github.com/googlesamples/android-ndk/tree/840858984e1bb8a7fab37c1b7c571efbe7d6eb75/hello-libs/gen-libs

He resuelto un problema similar utilizando dependencias de lib nativas externas que se empaquetan dentro de archivos jar. A veces, estas bibliotecas dependen de la architecture y se empaquetan juntas en un solo contenedor, a veces se dividen en varios archivos jar. así que escribí algunos buildscript para escanear las dependencias de jar para libs nativas y ordenarlas en las carpetas de lib de Android correctas. Además, esto también proporciona una forma de descargar dependencias que no se encuentran en los repos de maven, que actualmente es útil para hacer que JNA trabaje en Android porque no todos los archivos jar nativos están publicados en repositorys maven públicos.

 android { compileSdkVersion 23 buildToolsVersion '24.0.0' lintOptions { abortOnError false } defaultConfig { applicationId "myappid" minSdkVersion 17 targetSdkVersion 23 versionCode 1 versionName "1.0.0" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } sourceSets { main { jniLibs.srcDirs = ["src/main/jniLibs", "$buildDir/native-libs"] } } } def urlFile = { url, name -> File file = new File("$buildDir/download/${name}.jar") file.parentFile.mkdirs() if (!file.exists()) { new URL(url).withInputStream { downloadStream -> file.withOutputStream { fileOut -> fileOut << downloadStream } } } files(file.absolutePath) } dependencies { testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.3.0' compile 'com.android.support:design:23.3.0' compile 'net.java.dev.jna:jna:4.2.0' compile urlFile('https://github.com/java-native-access/jna/blob/4.2.2/lib/native/android-arm.jar?raw=true', 'jna-android-arm') compile urlFile('https://github.com/java-native-access/jna/blob/4.2.2/lib/native/android-armv7.jar?raw=true', 'jna-android-armv7') compile urlFile('https://github.com/java-native-access/jna/blob/4.2.2/lib/native/android-aarch64.jar?raw=true', 'jna-android-aarch64') compile urlFile('https://github.com/java-native-access/jna/blob/4.2.2/lib/native/android-x86.jar?raw=true', 'jna-android-x86') compile urlFile('https://github.com/java-native-access/jna/blob/4.2.2/lib/native/android-x86-64.jar?raw=true', 'jna-android-x86_64') compile urlFile('https://github.com/java-native-access/jna/blob/4.2.2/lib/native/android-mips.jar?raw=true', 'jna-android-mips') compile urlFile('https://github.com/java-native-access/jna/blob/4.2.2/lib/native/android-mips64.jar?raw=true', 'jna-android-mips64') } def safeCopy = { src, dst -> File fdst = new File(dst) fdst.parentFile.mkdirs() fdst.bytes = new File(src).bytes } def archFromName = { name -> switch (name) { case ~/.*android-(x86-64|x86_64|amd64).*/: return "x86_64" case ~/.*android-(i386|i686|x86).*/: return "x86" case ~/.*android-(arm64|aarch64).*/: return "arm64-v8a" case ~/.*android-(armhf|armv7|arm-v7|armeabi-v7).*/: return "armeabi-v7a" case ~/.*android-(arm).*/: return "armeabi" case ~/.*android-(mips).*/: return "mips" case ~/.*android-(mips64).*/: return "mips64" default: return null } } task extractNatives << { project.configurations.compile.each { dep -> println "Scanning ${dep.name} for native libs" if (!dep.name.endsWith(".jar")) return zipTree(dep).visit { zDetail -> if (!zDetail.name.endsWith(".so")) return print "\tFound ${zDetail.name}" String arch = archFromName(zDetail.toString()) if(arch != null){ println " -> $arch" safeCopy(zDetail.file.absolutePath, "$buildDir/native-libs/$arch/${zDetail.file.name}") } else { println " -> No valid arch" } } } } preBuild.dependsOn(['extractNatives'])