2015-12-02 97 views
0

切换到Android Studio之后,我开始看到了可怕的Android原生库消失,一旦应用程序被安装

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

错误。当我解压缩apk时,我可以在lib/armeabi文件夹下看到libmylib.so以及所有其他本地库(libmyotherlib.so和libtest.so),因此包装不应该成为问题...我决定根我的测试设备并查看/ data/app-lib下应用文件夹的实际内容,其中本机库应该安装后 - 我发现应用程序的一个本机库(libmylib.so)在应用程序后失踪安装在设备上。 libmylib.so和libmyotherlib.so是预建的.so文件,位于src/main/jniLibs中,而libtest.so是从src/main/jni中的test.c编译的。

这只在我切换到Android Studio后才开始;我已经验证过,在Eclipse ADT中使用相同代码构建的apks安装后,所有必需的库都存在于/data/app-lib/com.myapp.test-1下。

相关的build.gradle为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' 

} 

相关gradle.properties文件

android.useDeprecatedNdk=true 

下的src/main/JNI我只有test.c的

#include <jni.h> 

int main(){ 

    return 0; 
} 

and under src/main/jniLibs/armeabi我有

libmylib.so 
libmyotherlib.so 

相关Android.mk为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) 

相关/ data/app中-lib的内容安装的应用程序由Android工作室建成后:

[email protected] SL-K40:/ # ls /data/app-lib/com.myapp.test-1    
libmyotherlib.so 
libtest.so 

相关/数据/ APP-安装由Eclipse ADT构建的应用程序之后的lib内容:

[email protected] SL-K40:/ # ls /data/app-lib/com.myapp.test-1    
libmylib.so 
libmyotherlib.so 
libtest.so 

我不小心fo UND通过添加

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

我的build.gradle我能得到libmylib.so在安装后再次现身,但排除有在我的项目的任何NDK源代码。

第一个问题: 任何想法可能会发生什么吗?难道是因为mylib实际上是针对除armeabi以外的其他abi进行编译的,Android会放弃它,因为它的实际abi与它在apk内部进入的文件夹不匹配(我没有mylib的源代码)?我的问题听起来很像here,但是这个人似乎在最终安装的应用程序中只能看到一个共享库;我看到的都是我的共享库中的一个。

第二个问题: 在Android Studio构建中包含预构建.so文件的当前正确方法是什么? Cluesaroundthe 'net似乎根据Android Studio版本(我使用的是Android Studio 1.5,Gradle版本2.4,Android插件版本1.3。0)是否仍然需要将jniLibs.srcDir变量重定向到src/main/libs?

+0

我的猜测是它的某些gradle任务正在破坏构建 – Bhargav

+0

首先,您不需要root来访问**/data/app-lib/com.myapp.test-1/*中的库。 * –

+1

@AlexCohn是真的,但你确实需要root通过adb shell'ls -al/data/app-lib'列出/ data/app-lib的内容,而且我不想让我的应用程序的文件夹在运行时从名称上下文:: getApplicationInfo()。nativeLibraryDir – CCJ

回答

1

是的,最好的方法是定义jniLibs.srcDir,这样所有预建的库都可以从那里复制。

是的,ABI是最可能的问题来源。如果预建图书馆建于armeabi但设备(如当今绝大多数设备)支持armeabi-V7A,则安装程序会很乐意的...... V7A版本的未预建库复制到/data/app-lib/com.myapp.test-1,并且加载程序稍后会抱怨libmylib.so丢失。

您应该指示Android Studio仅构建一个ABI。如果你在Eclipse构建中没有做特别的事情,那么这很可能是armeabi

指示AS的方式取决于gradle插件的版本。

对于'com.android.tools.build:gradle:1.5.0'插件,我使用类似

android { 
    defaultConfig.ndk { 
     … 
     abiFilter 'armeabi' 
    } 

    splits { 
     abi { 
      enable true 
      reset() 
      include 'armeabi' 
     } 
    } 
} 

对于...... gradle这个实验性:0.2.0,我用

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

我没有必要启用在实验插件分裂,所以我不会误导你对语法的变化出现。

+0

嗯,很奇怪。我想知道/为什么libmyotherlib通过了安装过程呢?最终apk对所有的abis都有libtest,包括armeabi-v7a,但libmyotherlib只存在于armeabi中...... – CCJ

+1

安装程序是否可以检测到在设备的/ system/lib目录中有一个名为libmylib的库?如果是这样,这可以解释为什么libmyotherlib通过安装并且libmylib被抛出 - 我正在加载的实际库是在我的测试设备上的/ system/lib下找到的一个修改版本,因此和/或abi你提到的最适合的过滤将解释我看到的行为 – CCJ

相关问题