美文网首页
android N : java.lang.Unsatisfie

android N : java.lang.Unsatisfie

作者: Focus_jcl | 来源:发表于2017-03-18 20:31 被阅读1927次

    在Android N上使用 .so作为apk的第三方库的时候,会发生Java.lang.UnsatisfiedLinkError:

    09-27 12:17:01.280 D/ListenSoundModel( 3635): Load libxxxjni
    09-27 12:17:01.292 D/AndroidRuntime( 3635): Shutting down VM
    ——— beginning of crash
    09-27 12:17:01.293 E/AndroidRuntime( 3635): FATAL EXCEPTION: main
    09-27 12:17:01.293 E/AndroidRuntime( 3635): Process: com.qualcomm.xxx, PID: 3635
    09-27 12:17:01.293 E/AndroidRuntime( 3635): java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file “/data/app/xxxApp.apk”],nativeLibraryDirectories=[/data/app-lib/xxxApp, /system/lib64, /vendor/lib64]]] couldn’t find “libxxxjni.so”
    09-27 12:17:01.293 E/AndroidRuntime( 3635): at java.lang.Runtime.loadLibrary0(Runtime.java:972)
    09-27 12:17:01.293 E/AndroidRuntime( 3635): at java.lang.System.loadLibrary(System.java:1530)

    09-27 12:17:01.293 E/AndroidRuntime( 3635): at android.os.Handler.dispatchMessage(Handler.java:102)
    09-27 12:17:01.293 E/AndroidRuntime( 3635): at android.os.Looper.loop(Looper.java:154)

    这在google的变更说明有 介绍https://developer.android.com/preview/behavior-changes.html#ndk

    具体是什么原因呢,怎么解决这种问题呢,google给出了一个官方的解决办法(如上链接),这里也给出另外一种方法。

    首先,主要原因是google在N上对.so库的加载进行了限制,限制了so库指从部分指定的路径进行加载,不在这个路径的so提示
    java.lang.UnsatisfiedLinkError: dlopen failed: library “xxx.so” not found 或
    java.lang.UnsatisfiedLinkError: dlopen failed: library “/vendor/lib64/xxx.so” needed or dlopened by “/system/lib64/libnativeloader.so” is not accessible for the namespace “classloader-namespace” 或 其他异常错误提示。

    N上对so库加载的搜索路径方式为ld_library_path, runtime path, permit path,不在这个搜索路径下则加载失败。

    从代码层面看,主要是类加载器ClassLoader的相关处理,
    code1: (loadedApk.java getClassLoader()) check sdk version
    // DO NOT SHIP: this is a workaround for apps loading native libraries
    // provided by 3rd party apps using absolute path instead of corresponding
    // classloader; see http://b/26954419 for example.
    if (mApplicationInfo.targetSdkVersion <= 23) {
    libraryPermittedPath += File.pathSeparator + “/data/app”;
    }

    Code2: (loadedApk.java getClassLoader()) N add a new PermittedPath
    String libraryPermittedPath = mDataDir;

    Code3: (native_loader.cpp) use the new namespace rule with search path: ld_library_path, runtime path, permit path.

    在明白原因之后,
    解决办法则是将自己的so加入到允许路径的白名单里面,具体操作为,如果不改代码实现,则导出设备的/vendor/etc/public.libraries.txt 或/etc/public.libraries.txt文件,将so名字添加进去,在push到设备,重启即可。
    ------相关命令------
    退出 adb shell命令 : exit

    1、获得root权限:adb root 或则 eng版本手机 直接第三步

    2、设置/system为可读写:adb remount

    3、将hosts文件复制到PC:adb pull /system/etc/hosts.txt PC机上目录

    4、修改PC机上文件

    5、将PC机上文件复制到手机:adb push PC机上文件名 /system/etc/

    如果要查看是否修改成功,可以在PC上执行adb shell,运行cat /system/etc/hosts;或者在手机上运行cat /system/etc/hosts。

    将PC机上文件复制到手机:adb push <PC机上文件名> /system/etc/hosts

    rm -r xxx //删除名字为xxx的文件夹及其里面的所有文件

    rm xxx //删除文件xxx

    rmdir xxx //删除xxx的文件夹

    导出设备的/vendor/etc/public.libraries.txt 或/etc/public.libraries.txt文件,将so名字添加进去,在push到设备,重启即可
    ------相关命令------

    相关文章

      网友评论

          本文标题:android N : java.lang.Unsatisfie

          本文链接:https://www.haomeiwen.com/subject/fwrpnttx.html