[英]java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader
Is there someone who had experience with this error?有没有人遇到过这个错误?
java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/org.swig.simple-2/base.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]] couldn't find "liborg.swig.simple.example.so"
Error occurs when I load library by this way.当我以这种方式加载库时发生错误。
static {
System.loadLibrary("example");
}
I'm sure 'example' class is exist in the current folder.我确定当前文件夹中存在“示例”类。
I am currently working on an Android application which streams radio.我目前正在开发一个流广播的 Android 应用程序。 I use native decoder library which is called aacdecoder.
我使用称为 aacdecoder 的本机解码器库。 Everything was fine till app gets crash error on some Android devices.
一切都很好,直到应用程序在某些 Android 设备上出现崩溃错误。 It was really annoying.
这真的很烦人。 Because app was perfectly plays radio streams almost all devices but Samsung S6 and S6 Edge.
因为应用程序可以完美播放除三星 S6 和 S6 Edge 之外的几乎所有设备的无线电流。
Crash report says that崩溃报告说
Fatal Exception: java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file “/data/app/com.radyoland.android-1/base.apk”],nativeLibraryDirectories=[/data/app/com.radyoland.android-1/lib/arm64, /vendor/lib64, /system/lib64]]] couldn’t find “libaacdecoder.so”
at java.lang.Runtime.loadLibrary(Runtime.java:366)
at java.lang.System.loadLibrary(System.java:988)
at com.spoledge.aacdecoder.Decoder.loadLibrary(Decoder.java:187)
As you see that crash is saying that it could not load native library.如您所见,崩溃是说它无法加载本机库。 But why?
但为什么? First of all I checked my structure, If native library .so files located correctly.
首先,我检查了我的结构,如果本地库 .so 文件位置正确。
Seems everything was okay except this crazy error.似乎一切都很好,除了这个疯狂的错误。 Then after some research, I find out that some of android devices has 64-bit processors.
然后经过一些研究,我发现一些 android 设备具有 64 位处理器。 This devices generates and check arm64 folder to load native library.
该设备生成并检查 arm64 文件夹以加载本机库。 That was the problem.
这就是问题所在。 Because my project does not have arm64 folder.
因为我的项目没有 arm64 文件夹。 Here is the solution;
这是解决方案;
defaultConfig {
...
ndk {
abiFilters "armeabi-v7a", "x86", "armeabi", "mips"
}
}
You need to add this filters(abiFilters) to your app module's build.gradle files.您需要将此过滤器(abiFilters)添加到您的应用程序模块的 build.gradle 文件中。 So when your device try to run your app, it will check gradle file and understands that it should not generate any folder and use existing native library resources.
因此,当您的设备尝试运行您的应用程序时,它会检查 gradle 文件并了解它不应生成任何文件夹并使用现有的本机库资源。 Boom, almost solved.
砰,几乎解决了。 But still there is one more thing.
但还有一件事。
android.useDeprecatedNdk=true
Add this line to your gradle.properties to use deprecated Ndk.将此行添加到您的 gradle.properties 以使用已弃用的 Ndk。
Finally my app works on S6 and S6 Edge.最后,我的应用可以在 S6 和 S6 Edge 上运行。 I mean it works on every devices which has new 64-bit processors.
我的意思是它适用于所有具有新 64 位处理器的设备。
Update :更新 :
As of Dec/2019 armabi and mips are deprecated.截至 2019 年 12 月, armabi 和 mips 已弃用。 Supported ABIs are [arm64-v8a, armeabi-v7a, x86, x86_64]
支持的 ABI 是 [arm64-v8a, armeabi-v7a, x86, x86_64]
So, your code should be like this所以,你的代码应该是这样的
defaultConfig {
...
ndk {
abiFilters "arm64-v8a", "armeabi-v7a", "x86", "x86_64"
}
}
Please note that there's a naming convention.请注意,有一个命名约定。 Your lib needs to be called libexample.so .
您的库需要被称为 libexample.so 。
LoadLibrary("example") will look for libexample.so. LoadLibrary("example") 将查找 libexample.so。
The .so library needs to be inside the apk under the lib folder (since you are developing for Android, it needs to be under the lib/armeabi and lib/armeabi-v7a folders - why both folders ? some versions of Android look under lib/armeabi and some look under lib/armeabi-v7a ... se what works for you ). .so 库需要位于 lib 文件夹下的 apk 中(因为您正在为 Android 开发,所以它需要位于 lib/armeabi 和 lib/armeabi-v7a 文件夹下 - 为什么这两个文件夹?某些版本的 Android 位于 lib 下/armeabi 和一些在 lib/armeabi-v7a 下查看...看看对你有用的东西)。
Other things to look for :其他要寻找的东西:
make sure you compile for the correct architecture (if you compile for armeabi v5 it won't work on armeabiv7 or armeabiv7s ).确保为正确的体系结构进行编译(如果为 armeabi v5 进行编译,它将不适用于 armeabiv7 或 armeabiv7s )。
make sure your exported prototypes are used in the correct class (check the hello jni example. Your exposed functions need to look something like Java_mypackagename_myjavabridgeclass_myfunction).确保您导出的原型在正确的类中使用(检查 hello jni 示例。您的公开函数需要类似于 Java_mypackagename_myjavabridgeclass_myfunction)。
For example the function Java_com_example_sample_hello will translate in the java class com.example.sample , function hello.例如,函数 Java_com_example_sample_hello 将在 java 类 com.example.sample 中翻译,函数 hello。
This helped me.这对我有帮助。 Sharing it for someone who might come up with same issue.
分享给可能遇到同样问题的人。
android {
....
defaultConfig {
....
ndk {
abiFilters "armeabi", "armeabi-v7a", "x86", "mips"
}
}
}
What worked for me was to place the jniLibs folder under the "main" folder, just besides the "java" and "res" folders, for example project -> app -> src -> main -> jniLibs对我有用的是将 jniLibs 文件夹放在“main”文件夹下,除了“java”和“res”文件夹之外,例如 project -> app -> src -> main -> jniLibs
I had all the libraries with the correct names and each one placed on their respective architecture subfolder, but I still had the same exception;我拥有所有名称正确的库,每个库都放在各自的架构子文件夹中,但我仍然有同样的例外; even tried a lot of other SO answers like the accepted answer here, compiling a JAR with the .so libs, other placing of the jniLibs folder, etc.
甚至尝试了很多其他 SO 答案,例如此处接受的答案,使用 .so 库编译 JAR,jniLibs 文件夹的其他放置等。
For this project, I had to use Gradle 2.2 and Android Plugin 1.1.0 on Android Studio 1.5.1对于这个项目,我必须在 Android Studio 1.5.1 上使用 Gradle 2.2 和 Android Plugin 1.1.0
-if gradle.properties not available then first add that file and add android.useDeprecatedNdk=true
- 如果gradle.properties不可用,则首先添加该文件并添加
android.useDeprecatedNdk=true
-use this code in build.gradle - 在 build.gradle 中使用此代码
defaultConfig {
applicationId 'com.example.application'
minSdkVersion 16
targetSdkVersion 21
versionCode 11
versionName "1.1"
ndk {
abiFilters "armeabi"
}
}
` `
I use Android Studio 3.0 and encounter this problem.我使用 Android Studio 3.0 并遇到了这个问题。 And I'm sure app's build.gradle is OK.
而且我确定应用程序的 build.gradle 没问题。
Go to Run -> Edit Configurations -> Profiling, and disable "Enable advanced profiling".转到运行 -> 编辑配置 -> 分析,然后禁用“启用高级分析”。
This works for me.这对我有用。 Reference answer
参考答案
This is worked for me这对我有用
If your having .so file in armeabi then mention inside ndk that folder alone.如果您在 armeabi 中有 .so 文件,请在 ndk 中单独提及该文件夹。
defaultConfig {
applicationId "com.xxx.yyy"
minSdkVersion 17
targetSdkVersion 26
versionCode 1
versionName "1.0"
renderscriptTargetApi 26
renderscriptSupportModeEnabled true
ndk {
abiFilters "armeabi"
}
}
and then use this然后用这个
android.useDeprecatedNdk=true;
in gradle.properties file在 gradle.properties 文件中
What helped me was to register the source directory for jni files in the build.gradle file.帮助我的是在 build.gradle 文件中注册 jni 文件的源目录。 Add this to your gradle file:
将此添加到您的 gradle 文件中:
android {
sourceSets {
main {
jniLibs.srcDir '[YOUR_JNI_DIR]' // i.e. 'libs'
}
}
}
Some old gradle tools cannot copy .so files into build folder by somehow, manually copying these files into build folder as below can solve the problem:一些旧的 gradle 工具无法通过某种方式将 .so 文件复制到 build 文件夹中,手动将这些文件复制到 build 文件夹中可以解决问题:
build/intermediates/rs/{build config}/{support architecture}/
build config: beta/production/sit/uat构建配置:beta/production/sit/uat
support architecture: armeabi/armeabi-v7a/mips/x86支持架构:armeabi/armeabi-v7a/mips/x86
If you are using Android studio, just edit the gradle.properties in the root folder and add android.useDeprecatedNdk=true.如果您使用的是 Android Studio,只需编辑根文件夹中的 gradle.properties 并添加 android.useDeprecatedNdk=true。 Then edit the build.gradle file in your app's folder, set abiFilters as below:
然后编辑应用文件夹中的 build.gradle 文件,设置 abiFilters 如下:
android {
....
defaultConfig {
....
ndk {
abiFilters "armeabi", "armeabi-v7a", "x86", "mips"
}
}
}
If you use module with c++ code and have the same issue you could try如果您将模块与 c++ 代码一起使用并且遇到相同的问题,您可以尝试
Build -> Refresh Linked C++ Projects
Also, you should open some file from this module and do此外,您应该从此模块打开一些文件并执行
Build -> Make module "YourNativeLibModuleName"
Ensure you have included the different abiFilters, this enables Gradle know what ABI libraries to package into your apk.确保您已包含不同的 abiFilters,这使 Gradle 知道要将哪些 ABI 库打包到您的 apk 中。
defaultConfig {
ndk {
abiFilters "armeabi-v7a", "x86", "armeabi", "mips"
}
}
If you storing your jni libs in a different directory, or also using externally linked jni libs, Include them on the different source sets of the app.如果您将 jni 库存储在不同的目录中,或者还使用外部链接的 jni 库,请将它们包含在应用程序的不同源集中。
sourceSets {
main {
jni.srcDirs = ['src/main/jniLibs']
jniLibs.srcDir 'src/main/jniLibs'
}
}
Yet another crash cause and possible solution is described in this article: https://medium.com/keepsafe-engineering/the-perils-of-loading-native-libraries-on-android-befa49dce2db本文描述了另一个崩溃原因和可能的解决方案: https ://medium.com/keepsafe-engineering/the-perils-of-loading-native-libraries-on-android-befa49dce2db
Briefly:简要地:
in build.gradle在 build.gradle
dependencies {
implementation 'com.getkeepsafe.relinker:relinker:1.2.3'
}
in code在代码中
static {
try {
System.loadLibrary("<your_libs_name>");
} catch (UnsatisfiedLinkError e) {
ReLinker.loadLibrary(context, "<your_libs_name>");
}
}
System.loadLibrary
loads a shared library from lib
folder. System.loadLibrary
从lib
文件夹加载共享库。
What do you mean when saying "I'm sure 'example' class is exist in the current folder"? 您说“我确定当前文件夹中存在'example'类”是什么意思? You should put your .so library to
lib
folder. 您应该将.so库放入
lib
文件夹。
For me the problem was in NDK_ROOT not being set.对我来说,问题在于未设置 NDK_ROOT。
Check your console if:如果出现以下情况,请检查您的控制台:
NDK_ROOT = None [!] NDK_ROOT not defined. NDK_ROOT = 无 [!] NDK_ROOT 未定义。 Please define NDK_ROOT in your environment or in local.properties
请在您的环境或 local.properties 中定义 NDK_ROOT
Check if you have set:检查您是否设置了:
This could be device related issue.这可能是与设备相关的问题。
I was getting this error in MI devices only , code was working with all other devices.我只在 MI 设备中收到此错误,代码正在与所有其他设备一起使用。
This might help:这可能会有所帮助:
defaultConfig{
...
externalNativeBuild {
cmake {
cppFlags "-frtti -fexceptions"
}
}
}
Simple Solution with Pics
Step1: Add following code in build.gradle file under defaultConfig
ndk {
abiFilters "armeabi-v7a", "x86", "armeabi", "mips"
}
Example:[![enter image description here][1]][1]
Steo 2: Add following code in gradle.properties file
android.useDeprecatedNdk=true
Example: [![enter image description here][2]][2]
Step 3: Sync Gradle and Run the Project.
@Ambilpur
[1]: https://i.stack.imgur.com/IPw4y.png
[2]: https://i.stack.imgur.com/ByMoh.png
In my case After running the ndk-build
in the jni
folder the shared library was created under the libs
folder but the path specified in build.gradle就我而言,在
jni
文件夹中运行ndk-build
后,共享库是在libs
文件夹下创建的,但路径是在 build.gradle 中指定的
sourceSets.main {
jni.srcDirs = []
jniLibs.srcDir 'src/main/jniLibs'
}
so I need to move the created shared library to jnilibs
folder and it worked!所以我需要将创建的共享库移动到
jnilibs
文件夹并且它有效!
I have resolved my issue by adding these lines.
我通过添加这些行解决了我的问题。
defaultConfig {
ndk {
abiFilters "armeabi-v7a", "x86", "armeabi", "mips"
}
}
sourceSets {
main {
jni.srcDirs = ['src/main/jniLibs']
jniLibs.srcDir 'src/main/jniLibs'
}
}
Copy your "example.so" file inside /libs/(armeabi|armeabi-v7a|x86|...) .将“example.so”文件复制到 /libs/(armeabi|armeabi-v7a|x86|...) 中。 When using Android Studio, it's /app/src/main/jniLibs/(armeabi|armeabi-v7a|x86|...)
使用 Android Studio 时,它是 /app/src/main/jniLibs/(armeabi|armeabi-v7a|x86|...)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.