【发布时间】:2016-03-07 05:05:14
【问题描述】:
切换到Android Studio后,我开始看到可怕的
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 中使用相同代码构建的 apk 在安装后具有 /data/app-lib/com.myapp.test-1 下存在的所有必需库。
Android Studio 构建的相关 build.gradle:
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;
}
在 src/main/jniLibs/armeabi 我有
libmylib.so
libmyotherlib.so
Eclipse ADT 构建的相关 Android.mk:
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)
安装Android Studio构建的应用后的相关/data/app-lib内容:
root@SOLONE SL-K40:/ # ls /data/app-lib/com.myapp.test-1
libmyotherlib.so
libtest.so
安装Eclipse ADT构建的app后的相关/data/app-lib内容:
root@SOLONE SL-K40:/ # ls /data/app-lib/com.myapp.test-1
libmylib.so
libmyotherlib.so
libtest.so
我无意中发现通过添加
sourceSets {
main {
jni.srcDirs = []
}
}
对于我的 build.gradle,我可以让 libmylib.so 在安装后再次出现,但这排除了我的项目中有任何 NDK 源代码。
第一个问题: 知道这里可能会发生什么吗?难道 mylib 实际上是为 armeabi 以外的 abi 编译的,而 Android 正在丢弃它,因为它的实际 abi 与它在 apk 中的文件夹不匹配(我没有 mylib 的源代码)?我的问题听起来与讨论过的here 相似,但那个人似乎在最终安装的应用程序中只看到了一个共享库;除了我的一个共享库之外,我看到的都是。
第二个问题: 在 Android Studio 构建中包含预构建的 .so 文件的当前正确方法是什么? Clues around the 'net 似乎因 Android Studio 版本而异(我使用的是 Android Studio 1.5、Gradle 版本 2.4、Android 插件版本 1.3.0)是否仍然需要将 jniLibs.srcDir 变量重定向到src/main/libs?
【问题讨论】:
-
我的猜测是它的一些 gradle 任务正在破坏构建
-
首先,你不需要root来访问/data/app-lib/com.myapp.test-1/中的库
-
@AlexCohn 是的,但是您确实需要 root 才能通过 adb shell 'ls -al /data/app-lib' 列出 /data/app-lib 的内容,而我不想这样做必须在运行时从 Context::getApplicationInfo().nativeLibraryDir 获取我的应用程序文件夹的名称
-
@CCJ 如果您正在运行调试应用程序,则不需要:stackoverflow.com/a/7712173/4758618
标签: java android c android-studio android-ndk