当前位置:   article > 正文

Android: java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList...问题的解决方案

java.lang.unsatisfiedlinkerror: dalvik.system.pathclassloader[dexpathlist[[z

异常

导入第三方SDK并编译运行时,出现了:“Caused by: java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file “/system/framework/org.apache.http.legacy.boot.jar”, zip file “/data/app/com.yiguozhen.handheldsmart-SWfW3u7Cj8q39Ii-pdhONg==/base.apk”],nativeLibraryDirectories=[/data/app/com.yiguozhen.handheldsmart-SWfW3u7Cj8q39Ii-pdhONg==/lib/arm64, /data/app/com.yiguozhen.handheldsmart-SWfW3u7Cj8q39Ii-pdhONg==/base.apk!/lib/arm64-v8a, /system/lib64]]] couldn’t find "libidcard.so”问题:

原因分析

这个错误是so库加载问题,报错一般以 java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader开头。一般是程序在运行过程中调用System.loadLibrary(“xxxxxxxx”);是无法找到libxxxxxx.so文件导致的报错。首先,从表面分析,出现这异常的原因是apk运行的时候加载.so文件失败,而接下来,就可以从两方面入手解决问题:
1.检查项目中的so文件存放位置,配置,SO结构是否完整等;
2.配置正确的前提下,检查apk包中是否已经将so文件编译进去(可以通过压缩工具打开,apk的目录下会存在一个“lib”,这里存放的是所有配置的so文件)

解决方案

根据上面两种情况及猜想,就能对应的尝试解决方案:

对于分析的情况一,需要从以下几方面检查项目的配置:

1.检查jniLibs目录下是否都已经存在所需要的so文件,假如不存在,则需要根据设备的CPU型号对应的放入"arm64-v8a", “armeabi-v7a”, "armeabi"等对应的so文件

需要注意的是如果项目中存在多个sdk的情况,最好保持每个SO结构文件中的so文件保存一直,比如:armeabi和armeabi-v7a都有so库,我们可以引入armeabi-v7a这个架构,然后把armeabi里的文件复制一份进anmeabi-v7a目录下,然后重新编译。armeabi和armeabi-v7a文件不一致也有可能导致程序异常。

2.检查项目的build.gradle文件(app目录下),对于ndk的配置是否正确:
在这里插入图片描述
SO结构文件在build文件中必须对应的配置。

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.0"

    defaultConfig {
        applicationId ""
        minSdkVersion 19
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"
        compileSdkVersion 28
        buildToolsVersion "28.0.3"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

//        multiDexEnabled true

        ndk {
            abiFilters "arm64-v8a", "armeabi-v7a"
        }
//        lintOptions {
//            abortOnError false
//        }
    }


    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    sourceSets {
        main {
            jni.srcDirs = []
            jniLibs.srcDirs = ['src/main/jniLibs']
        }
    }


}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

ndk指定了可以支持的设备的SO结构,其他的都会被过滤。
3.检查so文件的引入是否正确:

android{
...
    sourceSets {
        main {
            jni.srcDirs = []
            jniLibs.srcDirs = ['src/main/jniLibs']
        }
    }
...
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

sourceSets一定要放在android的代码块内。否则,配置不正确。同时,“jniLibs.srcDirs”最好写完整路径。
网上也有人这样写的:

android{
...
    sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
        }
    }
...
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

这样的写法,如果是单一sdk的集成的话,可能没有问题,但如果多个sdk或者多种类型的so文件同时集成的时候,so将无法编译到apk文件中(本人就遇到了这个问题,最后按照前者配置方式解决了问题)
对于配置问题,主要可以从以上几种方式去尝试解决问题。

对于分析的情况二,可以通过查看apk的方式确定so文件是否被编译到apk中:
1.进入项目,找到对应的apk文件:

在这里插入图片描述
2.使用压缩工具或者adb命令查看当前apk目录:
在这里插入图片描述
3.检查lib目录下的文件是否存在报错log中缺少的文件,同时和项目的jniLibs对应的目录下的文件进行比较,检查文件是否全部编译进去:
在这里插入图片描述
项目中的so文件:
在这里插入图片描述

最后,还有一种情况:集成的so文件不支持设备的SO结构,比如:
arm64-v8a 支持64位系统设备
armeabi-v7a 支持32位系统设备
armeabi 向下兼容,假如前两个都没有,则在apk运行的时候,就会找armeabi文件
因此,根据编译运行的设备型号,必须要有相应支持的so文件,这样一一匹配才能正常集成并使用so文件。

以上就是我遇到问题的解决方案,希望对应大家有所帮助。不足之处,欢迎指出。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/143255
推荐阅读
相关标签
  

闽ICP备14008679号