Android5+运行带有so文件的项目时候找不到so文件异常
最近做项目出了一个bug项目中用到so文件,在5.0以上的手机上会报一个初始化异常错误,并提示找不到so文件。lib里目录结构类似如下
在Android5以下都没有问题,在5.0以上会报错,并提示找不到second.so文件。
解决方法
移除armeabi-v7a文件夹或者保证armeabi-v7a和armeabi两个文件夹下的so文件一致,即数量和名称都一样。
问题原因
原因是在stackoverflow找到的,大致意思如下:Android中的so文件都是在Android APP安装的的时候复制到data/data/包名 下边的。Android 5以前的Android系统会先后查看armeabi-v7a和armeabi文件夹下的so文件,取其并集放置到APP目录下,而Android5以后的系统会先检查armeabi-v7a文件夹,如果有so文件,就只会把armeabi-v7a目录下的so文件拷贝懂啊APP目录下,如果armeabi-v7a文件夹下没有so文件,则会拷贝armeabi中的so文件。
错误:couldn't find "libBaiduMapSDK_v2_4_1.so"
java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/xxx.xxxxx.xxx/base.apk"],nativeLibraryDirectories=[/data/app/xxx.xxxxx.xxx/lib/arm64, /vendor/lib64, /system/lib64]]] couldn't find "libBaiduMapSDK_v2_4_1.so" at java.lang.Runtime.loadLibrary(Runtime.java:366) at java.lang.System.loadLibrary(System.java:989) at com.baidu.mapapi.BMapManager.<clinit>(Unknown Source) at xxx.xxxxx.xxx.XxxxApplication.initEngineManager(XxxxApplication.java:195) at xxx.xxxxx.xxx.XxxxApplication.onCreate(XxxxApplication.java:105) at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1016) at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4797) at android.app.ActivityThread.access$1500(ActivityThread.java:176) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1498) at android.os.Handler.dispatchMessage(Handler.java:111) at android.os.Looper.loop(Looper.java:194) at android.app.ActivityThread.main(ActivityThread.java:5578) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:955) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:750) 解决方案: 生成对应版本的so文件:arm64/XX.so 这些手机的共同点是使用了64位CPU+Android 5.0(支持64位)。 看起来问题应该是由于Apk内没有包含arm64-v8a版本的so文件导致的,但百度地图SDK一直都没有提供过除了armeabi之外版本的so文件。之前遇到armeabi-v7a版本的问题时,是通过复制armeabi目录的文件到armeabi-v7a目录来解决的,看起来这两种版本的代码可以兼容运行,但这个方法在arm64-v8a版本上没法奏效,将armeabi目录的文件复制到arm64-v8a目录再打包运行App,不会出现so找不到的错误了,但是会出现新的错误。错误:java.lang.UnsatisfiedLinkError: No implementation found for double
/test.com.yu E/AndroidRuntime: FATAL EXCEPTION: main Process: test.com.yu, PID: 12004 java.lang.UnsatisfiedLinkError: No implementation found for double test.com.myjni.JniUtils.sum(double, double) (tried Java_test_com_myjni_JniUtils_sum and Java_test_com_myjni_JniUtils_sum__DD) at test.com.myjni.JniUtils.sum(Native Method) 解决方案: 方法名,类名,.h,.c文件的名称不对,检查一遍,遵循规则
错误:java.lang.UnsatisfiedLinkError: com.study.jnilearn.HelloWorld.sayHello
解决方法:Java在调用native(本地)方法之前,需要先加载动态库。如果在未加载动态之前就调用native方法,会抛出找不到动态链接库文件的异常。
错误:> com.android.ide.common.internal.LoggedErrorException: Failed to run command: D:\ndk\ndk-build.cmd NDK_PROJECT_PATH=null APP_BUILD_SCRIPT=F:\androidstudio\test\hellojni\build\ndk\debug\Android.mk APP_PLATFORM=android-
19 NDK_OUT=F:\androidstudio\test\hellojni\build\ndk\debug\obj NDK_LIBS_OUT=F:\androidstudio\test\hellojni\build\ndk\debug\lib APP_ABI=armeabi,armeabi-v7aError Code:
2Output: make.exe: *** No rule to make target `F:\androidstudio\test\hellojni\build\ndk\debug\obj/
local/armeabi/objs/jnimain/F_\androidstudio\test\hellojni\src\main\jni
'
, needed by `F:\androidstudio\test\hellojni\build\ndk\debug\obj/local/armeabi/objs/jnimain/F_\androidstudio\test\hellojni\src\main\jni\hellojni.o
'. Stop.
解决方案:这是NDK在Windows下一个bug,当只编译一个文件时出现,解决方法就是再添加一个空的文件即可。原文见
http://ph0b.com/android-studio-gradle-and-ndk-integration/:
错误:> failed to find Build Tools revision
19.0.
3
解决方案:这个Build Tools是指“Android SDK Build-tools”,打开SDK Manager勾选相应版本(例如这里是19.0.3)安装即可。
This may come from a current NDK bug on Windows, when there is only one source file to compile. You only need to add one empty source to make it work again.
Could not determine the dependencies of task ':hellojni:compileArmDebugJava'.
FAILURE: Build failed with an exception.
productFlavors{
productFlavors {
Execution failed for task ':hellojni:compileDebugNdk'.
A problem occurred evaluating project ':app'.
Execution failed for task ':hellojni:compileDebugNdk'.