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

13 篇文章 0 订阅

异常

导入第三方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']
        }
    }


}

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

android{
...
    sourceSets {
        main {
            jni.srcDirs = []
            jniLibs.srcDirs = ['src/main/jniLibs']
        }
    }
...
}

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

android{
...
    sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
        }
    }
...
}

这样的写法,如果是单一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文件。

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

  • 8
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

易小四

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值