Libs nativas de Android desaparecen una vez que la aplicación está instalada

Después de cambiar a Android Studio, comencé a ver el temido

java.lang.UnsatisfiedLinkError: dlopen failed: library '/data/app-lib/com.myapp.test-1/libmylib.so' not found 

error. Cuando descomprimo el apk, puedo ver libmylib.so junto con todas las demás bibliotecas nativas (libmyotherlib.so y libtest.so) debajo de la carpeta lib / armeabi, por lo que el empaquetado no debería ser el problema … decidí rootear Mi dispositivo de prueba y verifico el contenido real de la carpeta de mi aplicación en / data / app-lib, donde deberían estar sus bibliotecas nativas después de la instalación. Descubrí que una de las bibliotecas nativas de mi aplicación (libmylib.so) faltaba después de la aplicación está instalado en un dispositivo. libmylib.so y libmyotherlib.so son archivos .so precomstackdos ubicados en src / main / jniLibs, y libtest.so se comstack desde test.c en src / main / jni.

Esto solo comenzó después de que cambié a Android Studio; Verifiqué que los apks creados a partir del mismo código en Eclipse ADT tienen todas las bibliotecas necesarias presentes en /data/app-lib/com.myapp.test-1 después de la instalación.

Build.gradle relevante para la comstackción de Android Studio:

 apply plugin: 'com.android.application' android { compileSdkVersion 23 buildToolsVersion "21.1.2" defaultConfig { applicationId "com.myapp.test" minSdkVersion 17 targetSdkVersion 23 versionCode 1 versionName "1.0" ndk{ moduleName "test"//testing ndk integration } } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } repositories { // You can also use jcenter if you prefer mavenCentral() } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' //android support libs etc. compile 'com.android.support:appcompat-v7:23.1.0' compile 'com.android.support:support-v13:23.1.0' } 

Archivo gradle.properties relevante

 android.useDeprecatedNdk=true 

Bajo src / main / jni solo tengo test.c

 #include  int main(){ return 0; } 

y bajo src / main / jniLibs / armeabi tengo

 libmylib.so libmyotherlib.so 

Android.mk relevante para la construcción de Eclipse ADT:

 include $(CLEAR_VARS) LOCAL_MODULE := test LOCAL_SRC_FILES += test.c include $(BUILD_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := myotherlib LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libmyotherlib.so LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := mylib LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libmylib.so LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include include $(PREBUILT_SHARED_LIBRARY) 

Contenido relevante / data / app-lib después de instalar la aplicación creada por Android Studio:

 root@SOLONE SL-K40:/ # ls /data/app-lib/com.myapp.test-1 libmyotherlib.so libtest.so 

Contenido relevante / data / app-lib después de instalar la aplicación creada por Eclipse ADT:

 root@SOLONE SL-K40:/ # ls /data/app-lib/com.myapp.test-1 libmylib.so libmyotherlib.so libtest.so 

Encontré accidentalmente que al agregar

 sourceSets { main { jni.srcDirs = [] } } 

para mi build.gradle puedo hacer que libmylib.so aparezca nuevamente después de la instalación, pero esto impide tener cualquier código fuente de NDK en mi proyecto.

Primera pregunta: ¿ Alguna idea de lo que podría estar pasando aquí? ¿Podría ser que mylib en realidad se compiló para un abi distinto del armeabi y Android lo está descartando porque su abi real no coincide con la carpeta en la que se incluyó dentro de la apk (no tengo el código fuente de mylib)? Mi problema parece similar al que se discutió aquí , pero esa persona parecía ver solo una biblioteca compartida en la aplicación final instalada; Estoy viendo todas menos una de mis bibliotecas compartidas.

Segunda pregunta: ¿Cuál es la forma correcta actual de incluir archivos .so precomstackdos en una comstackción de Android Studio? Las pistas alrededor de la red parecen variar enormemente según la versión de Android Studio (estoy usando Android Studio 1.5, Gradle versión 2.4, Android plugin versión 1.3.0) ¿Es necesario redirigir la variable jniLibs.srcDir a src / main / libs?

Sí, el mejor enfoque es definir jniLibs.srcDir de modo que todas las bibliotecas creadas previamente puedan copiarse desde allí.

Sí, el ABI es la fuente más probable del problema. Si la biblioteca precomstackda fue construida para armeabi pero el dispositivo (como la gran mayoría de los dispositivos hoy en día) es compatible con armeabi-v7a , entonces el instalador felizmente copiará las versiones … v7a de sus bibliotecas no precomstackdas a / data / app-lib / com .myapp.test-1 , y el cargador se quejará más tarde de que falta libmylib.so .

Debe indicar a Android Studio que solo genere una ABI. Si no hiciste algo especial en la comstackción de Eclipse, entonces es muy probable que sea armeabi .

La forma de instruir a AS depende de la versión del plugin gradle.

Para el complemento ‘com.android.tools.build:gradle:1.5.0’ , uso algo como

 android { defaultConfig.ndk { … abiFilter 'armeabi' } splits { abi { enable true reset() include 'armeabi' } } } 

Para … gradle-experimental: 0.2.0 , yo uso

 model { android.ndk { … abiFilters += 'armeabi' } } 

No tuve la necesidad de habilitar las divisiones en el complemento experimental , por lo que no te engañaré sobre los cambios de syntax allí.