文章目录

  • 一、问题描述
  • 二、问题排查
  • 三、解决方案

一、问题描述


NDK 开发 , 在调用 JNI 对应 Java 类时 , 静态代码块中 System.loadLibrary 语句调用时 , 报如下错误 ;

    static {System.loadLibrary("openssl");}
2020-12-01 10:35:48.993 20837-20837/? E/AndroidRuntime: FATAL EXCEPTION: mainProcess: kim.hsl.dex, PID: 20837java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/kim.hsl.dex-WPNFatgeDiPkh3jHexDmDg==/base.apk"],nativeLibraryDirectories=[/data/app/kim.hsl.dex-WPNFatgeDiPkh3jHexDmDg==/lib/arm64, /data/app/kim.hsl.dex-WPNFatgeDiPkh3jHexDmDg==/base.apk!/lib/arm64-v8a, /system/lib64, /hw_product/lib64, /system/product/lib64]]] couldn't find "libopenssl.so"at java.lang.Runtime.loadLibrary0(Runtime.java:1067)at java.lang.Runtime.loadLibrary0(Runtime.java:1007)at java.lang.System.loadLibrary(System.java:1668)at kim.hsl.multipledex.OpenSSL.<clinit>(OpenSSL.java:13)at kim.hsl.multipledex.OpenSSL.getBytes(OpenSSL.java:30)at kim.hsl.multipledex.ProxyApplication.attachBaseContext(ProxyApplication.java:124)at android.app.Application.attach(Application.java:358)at android.app.Instrumentation.newApplication(Instrumentation.java:1168)at android.app.LoadedApk.makeApplication(LoadedApk.java:1382)at android.app.ActivityThread.handleBindApplication(ActivityThread.java:7341)at android.app.ActivityThread.access$2400(ActivityThread.java:251)at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2280)at android.os.Handler.dispatchMessage(Handler.java:110)at android.os.Looper.loop(Looper.java:219)at android.app.ActivityThread.main(ActivityThread.java:8375)at java.lang.reflect.Method.invoke(Native Method)at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1055)

二、问题排查


出现上述错误 , 就是 打包的 so 动态库没有找到 , 有很多问题都会导致该错误 , 如 build.gradle 中没有配置对应的 CPU 架构 , NDK 中调用的外部动态或静态依赖库的 CPU 架构不匹配 ;

这里我遇到的问题是 主应用 与 依赖库的 CPU 架构不匹配导致 ;

创建项目时选择如下选项 , 自动生成的 build.gradle 中默认生成 arm64-v8a, armeabi-v7a, x86, x86_64 四种 CPU 架构的动态库 , 这就比较坑 , 一般开发时只编译 armeabi-v7a 这一种 CPU 架构的动态库 ;

在主应用中 , 选择了 C++ 支持 , 系统自动生成的配置如下 :

plugins {id 'com.android.application'id 'kotlin-android'
}android {compileSdkVersion 29buildToolsVersion "30.0.2"defaultConfig {applicationId "kim.hsl.myapplication"minSdkVersion 18targetSdkVersion 29versionCode 1versionName "1.0"testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"externalNativeBuild {cmake {cppFlags ""}}}buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'}}externalNativeBuild {cmake {path "src/main/cpp/CMakeLists.txt"version "3.10.2"}}compileOptions {sourceCompatibility JavaVersion.VERSION_1_8targetCompatibility JavaVersion.VERSION_1_8}kotlinOptions {jvmTarget = '1.8'}
}dependencies {implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"implementation 'androidx.core:core-ktx:1.3.2'implementation 'androidx.appcompat:appcompat:1.2.0'implementation 'com.google.android.material:material:1.2.1'implementation 'androidx.constraintlayout:constraintlayout:2.0.4'testImplementation 'junit:junit:4.+'androidTestImplementation 'androidx.test.ext:junit:1.1.2'androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}

上述 android / defaultConfig / externalNativeBuild / cmake / abiFilters 配置中没有配置 CPU 架构 , 没有配置 abiFilters CPU 架构选项 , 因此默认生成 arm64-v8a, armeabi-v7a, x86, x86_64 四种 CPU 架构的动态库 ;

下图是主应用生成的 so 动态库 :

可以明显看到 主应用的依赖库生成了 四种 CPU 架构的动态库 , 我们使用的 libopenssl.so 动态库只有 armeabi-v7a 架构的 , 当在 arm64-v8a 架构的手机中调用 OpenSSL 所在的类时 , 在 static 静态代码块中的 System.loadLibrary 调用时就会报错 ;

该应用生成了 arm64-v8a 架构的动态库 , 但是生成的不全 , 导致上述问题 , 解决方案是干脆不生成 arm64-v8a 架构的动态库 , 只生成 armeabi-v7a 架构动态库 , arm64-v8a 架构的手机会向下兼容 armeabi-v7a 架构动态库 , 因此只编译生成 armeabi-v7a 架构动态库即可 ;

在另一个主应用的 Android Library 中 , 其也使用了 NDK , 并且使用了外部依赖库 OpenSSL 静态库 , 在 Ubuntu 中只交叉编译了 armeabi-v7a 架构的静态库 , 因此不能生成 arm64-v8a 的动态库 ;

下图是依赖库生成的 so 动态库 :

目前的主流手机都是 arm64-v8a 或 armeabi-v7a 手机 , x86 和 x86_64 手机很少 , 一般不进行匹配 ;

一般的高端机型都是 arm64-v8a 架构的 , 几年前的机型可能是 armeabi-v7a 架构的 ;

arm64-v8a 架构的手机 可以兼容使用 armeabi-v7a 架构的动态库 ;

不过要注意一点 , 前提是没有配置 arm64-v8a 架构 , 如果配置了 arm64-v8a 架构 , 但是没有对应 so 库 , 那就会出现上述错误 ;

三、解决方案


解决方案 : 全部配置 armeabi-v7a 架构 , 这样在所有的手机中只存在 armeabi-v7a 架构 的动态库 , 系统查找时 , 就不会查找

android / defaultConfig / externalNativeBuild / cmake / abiFilters 配置 abiFilters 'armeabi-v7a' 即可 ;

plugins {id 'com.android.application'id 'kotlin-android'
}android {compileSdkVersion 29buildToolsVersion "30.0.2"defaultConfig {applicationId "kim.hsl.myapplication"minSdkVersion 18targetSdkVersion 29versionCode 1versionName "1.0"testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"externalNativeBuild {cmake {cppFlags ""abiFilters 'armeabi-v7a'}}}buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'}}externalNativeBuild {cmake {path "src/main/cpp/CMakeLists.txt"version "3.10.2"}}compileOptions {sourceCompatibility JavaVersion.VERSION_1_8targetCompatibility JavaVersion.VERSION_1_8}kotlinOptions {jvmTarget = '1.8'}
}dependencies {implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"implementation 'androidx.core:core-ktx:1.3.2'implementation 'androidx.appcompat:appcompat:1.2.0'implementation 'com.google.android.material:material:1.2.1'implementation 'androidx.constraintlayout:constraintlayout:2.0.4'testImplementation 'junit:junit:4.+'androidTestImplementation 'androidx.test.ext:junit:1.1.2'androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}

主应用中生成的 动态库 , 只剩成了 armeabi-v7a 架构的动态库 ;

依赖库中还是生成的 armeabi-v7a 架构的动态库 ;

问题解决 ;

如果非要配置 arm64-v8a 架构 , 但是一旦配置上 , 所有的在 NDK 中使用到的依赖库 如 OpenSSL , FFMPEG , RTMP , FAAC , OpenCV 等 , 都必须一式两份 , 一份 armeabi-v7a 架构的静态/动态 依赖库 , 一份 arm64-v8a 架构的 静态 / 动态 依赖库 ; ( 很麻烦 , APK 编译后也很大 , 不推荐 )

【错误记录】NDK 报错 java.lang.UnsatisfiedLinkError 的一种处理方案 ( 主应用与依赖库 Module 的 CPU 架构配置不匹配导致 )相关推荐

  1. 启动tomcat 报错java.lang.UnsatisfiedLinkError

    在IDEA中启动tomcat,报错 java.lang.UnsatisfiedLinkError: D:\apache-tomcat-8.5.31\bin\tcnative-1.dll: Can't ...

  2. 【错误记录】NDK 导入外部 so 动态库报错 ( java.lang.UnsatisfiedLinkError | Android Studio 配置外部 so 动态库两种方法 )

    文章目录 一.报错信息 二.解决方案 ( Android Studio 配置外部 so 动态库两种方法 ) 1.jniLibs 目录存放 2.libs 目录存放 一.报错信息 外部引用 so 动态库 ...

  3. so调用报错 java.lang.UnsatisfiedLinkError: No implementation found for ...

    最近在做一个NDK的Android项目,需要将cpp代码打包生成so库. 为了方便,直接将之前的一个项目拿过来,将cpp代码拷贝进来,修改了Android.mk文件,ndk-build成功生成so库. ...

  4. android内置第三方APP为系统应用,第三方APP内置到/system/app目录下报错java.lang.UnsatisfiedLinkError,so文件不加载

    项目场景: 在无系统签名的情况下,将第三方APP内置到/system/app目录下,可以将第三方应用变为系统应用,用户无法直接卸载.不过前提是手机需要root. 问题描述 使用es文件管理工具将第三方 ...

  5. IDEA springboot启动报错java.lang.UnsatisfiedLinkError: no tcnative-1 in java.library.path

    IDEA springboot启动报错: java.lang.UnsatisfiedLinkError: no tcnative-1 in java.library.path: [D:\Java\bi ...

  6. Centos 安装Eclipse报错java.lang.UnsatisfiedLinkError: Could not load SWT library

    在CentOs上安装Eclipse时报错: !ENTRY org.eclipse.osgi 4 0 2017-08-15 00:22:12.612 !MESSAGE Application error ...

  7. 【错误记录】Android Studio 导入外部 so 动态库报错 ( java.lang.UnsatisfiedLinkError | 指定 APK 打包动态库的 CPU 架构 )

    文章目录 一.报错信息 二.解决方案 ( 指定 APK 打包动态库的 CPU 架构 ) 一.报错信息 外部引用 so 动态库 , 如果只有一个 armeabi-v7a 的动态库 , 那么如果在 arm ...

  8. 解决tomcat运行报错java.lang.UnsatisfiedLinkError: apache-tomcat-7.0.37\bin\tcnative-1.dll:Can load AMD 64

    http://www.apache.org/dist/tomcat/tomcat-connectors/native/ 到该地址下下载一个tomcat-native-1.2.2-win32-bin压缩 ...

  9. Cookie报错java.lang.IllegalArgumentException

    项目中做自动登录和保存密码时,Cookie报错Java.lang.IllegalArgumentException,上google查了下 在http://hi.baidu.com/xtxycy/blo ...

最新文章

  1. 赵雅智_android多线程下载带进度条
  2. 透过 3.0 Preview 看 Dubbo 的云原生变革
  3. 开发高性能JAVA应用程序基础(内存篇)
  4. 设计模式--享元模式实现C++
  5. 守护进程之守护进程的特征
  6. linux终端下载notepad,在Linux系统上安装NotePad++的三种方法介绍
  7. 需要掌握的flex知识点
  8. logisitic 回归 +极大似然法 + 梯度下降法 (迭代优化)
  9. Matlab中隐函数绘制方法
  10. 开箱测评丨VEAZEN VZ200民谣吉他
  11. Referrer、Referrer-policy
  12. 台积电股价突破万亿大关 创下台股历史新高
  13. logcat 命令行用法
  14. ping命令的常用参数
  15. 软考高项目:项目人力资源管理真题
  16. 【Python数学建模】nba预测,基于退役球员数据预测现役球员入选名人堂的可能性
  17. squid代理服务器(正向代理与反向代理)
  18. Mysql—数据模型
  19. c语言程序设计感触,c语言程序设计报告书体会.doc
  20. Python计算机视觉编程学习笔记 四 照相机模型与增强现实

热门文章

  1. POWER-BI开发版功能简介
  2. maven nexus memory optimization
  3. TCP/IP 协议簇 端口 三次握手 四次挥手 11种状态集
  4. jQuery Layer 弹层组件
  5. 【BZOJ-2669】局部极小值 状压DP + 容斥原理
  6. (转)浅谈HTML5与css3画饼图!
  7. 我的第一个Windows Phone 7应用程序
  8. 如何比较js 浮点数
  9. banner手动切换效果
  10. BZOJ1935 园丁的烦恼