java.lang.UnsatisfiedLinkError:dalvik.system.PathClassLoader

时间:2014-11-28 10:30:47

标签: android c++ swig android-library

是否有人遇到此错误?

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"

通过这种方式加载库时发生错误。

static {
    System.loadLibrary("example");
}

我确定'示例' class存在于当前文件夹中。

18 个答案:

答案 0 :(得分:45)

请注意,这是一个命名惯例。你的lib需要被称为libexample.so。

LoadLibrary("示例")将查找libexample.so。

.so库需要在lib文件夹下的apk下面(因为你正在为Android开发,它需要在lib / armeabi和lib / armeabi-v7a文件夹下 - 为什么这两个文件夹?某些版本的Android看看lib / armeabi,有些看看lib / armeabi-v7a ... se什么对你有用。)

要寻找的其他事项:

  • 确保为正确的架构进行编译(如果您为armeabi v5编译,它将无法在armeabiv7或armeabiv7上工作)。

  • 确保导出的原型在正确的类中使用(请查看hello jni示例。您的公开函数需要看起来像Java_mypackagename_myjavabridgeclass_myfunction)。

例如函数Java_com_example_sample_hello将在java类com.example.sample中转换,函数hello。

答案 1 :(得分:24)

这对我有帮助。为可能提出相同问题的人分享。

android {
    ....
    defaultConfig {
        ....
        ndk {
            abiFilters "armeabi", "armeabi-v7a", "x86", "mips"
        }
    }
}

答案 2 :(得分:17)

我目前正在开发一个流式广播的Android应用程序。我使用原生解码器库,称为aacdecoder。一切都很好,直到应用程序在某些Android设备上出现崩溃错误。这真的很烦人。因为应用程序完全播放几乎所有设备的无线电流,但三星S6和S6 Edge。

崩溃报告说

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)

正如您所看到的那样,崩溃说它无法加载本机库。但为什么?首先,我检查了我的结构,如果本机库.so文件位置正确。

除了这个疯狂的错误外,似乎一切都还好。然后经过一些研究,我发现一些Android设备有64位处理器。此设备生成并检查arm64文件夹以加载本机库。那就是问题所在。因为我的项目没有arm64文件夹。这是解决方案;

defaultConfig {
    ...

    ndk {
        abiFilters "armeabi-v7a", "x86", "armeabi", "mips"
    }

}

您需要将此过滤器(abiFilters)添加到app模块的build.gradle文件中。因此,当您的设备尝试运行您的应用时,它将检查gradle文件,并了解它不应生成任何文件夹并使用现有的本机库资源。轰,几乎解决了。但还有一件事。

android.useDeprecatedNdk=true

将此行添加到gradle.properties以使用已弃用的Ndk。

最后我的应用程序适用于S6和S6 Edge。我的意思是它适用于每个拥有新64位处理器的设备。

答案 3 :(得分:10)

对我来说有用的是将jniLibs文件夹 放在 下的“main”文件夹中,除了“java”和“res”文件夹之外,例如项目 - > app - > src - >主要 - > jniLibs

我的所有库都有正确的名称,每个库都放在各自的架构子文件夹中,但我仍然有相同的异常;甚至尝试了很多其他的SO答案,比如这里接受的答案,用.so libs编译JAR,jniLibs文件夹的其他放置等等。

对于这个项目,我不得不在Android Studio 1.5.1上使用Gradle 2.2和Android插件1.1.0

答案 4 :(得分:8)

-if gradle.properties 不可用,然后首先添加该文件和 加 android.useDeprecatedNdk=true

- 在build.gradle中使用此代码

defaultConfig {
    applicationId 'com.example.application'
    minSdkVersion 16
    targetSdkVersion 21
    versionCode 11
    versionName "1.1"
    ndk {
        abiFilters "armeabi"
    }
}

`

答案 5 :(得分:7)

我使用Android Studio 3.0并遇到此问题。 而且我确定应用程序的build.gradle还可以。

转到Run - >编辑配置 - >分析和禁用"启用高级分析"。

这对我有用。 Reference answer

答案 6 :(得分:6)

这对我有用

如果你在armeabi中有.so文件,那么单独在ndk中提到该文件夹​​。

defaultConfig {
        applicationId "com.xxx.yyy"
        minSdkVersion 17
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        renderscriptTargetApi 26
        renderscriptSupportModeEnabled true
        ndk {
            abiFilters "armeabi"
        }
    }

然后使用此

android.useDeprecatedNdk=true;
gradle.properties文件中的

答案 7 :(得分:5)

一些旧的gradle工具无法以某种方式将.so文件复制到build文件夹中,手动将这些文件复制到build文件夹中可以解决问题:

build/intermediates/rs/{build config}/{support architecture}/

build config:beta / production / sit / uat

支持架构:armeabi / armeabi-v7a / mips / x86

答案 8 :(得分:3)

如果您使用的是Android工作室,只需编辑根文件夹中的gradle.properties并添加android.useDeprecatedNdk = true。然后编辑应用程序文件夹中的build.gradle文件,将abiFilters设置如下:

android {
....
defaultConfig {
    ....
    ndk {
        abiFilters "armeabi", "armeabi-v7a", "x86", "mips"
    }
}
}

答案 9 :(得分:3)

帮助我的是在build.gradle文件中注册jni文件的源目录。 将其添加到您的gradle文件:

android {
    sourceSets {
        main {
            jniLibs.srcDir '[YOUR_JNI_DIR]' // i.e. 'libs'
        }
    }
}

答案 10 :(得分:2)

如果您使用带有c ++代码的模块并遇到相同的问题,可以尝试

Build -> Refresh Linked C++ Projects

此外,您应该从此模块打开一些文件并执行

Build -> Make module "YourNativeLibModuleName"

答案 11 :(得分:1)

本文还介绍了另一个崩溃原因和可能的解决方案: https://medium.com/keepsafe-engineering/the-perils-of-loading-native-libraries-on-android-befa49dce2db

<强>简言之:
在build.gradle中

dependencies {
    implementation 'com.getkeepsafe.relinker:relinker:1.2.3'
}

代码

static {
    try {
        System.loadLibrary("<your_libs_name>");
    } catch (UnsatisfiedLinkError e) {
        ReLinker.loadLibrary(context, "<your_libs_name>");
    }
}

答案 12 :(得分:1)

确保您包含了不同的abiFilter,这使Gradle知道将哪些ABI库打包到您的apk中。

defaultConfig {
 ndk { 
       abiFilters "armeabi-v7a", "x86", "armeabi", "mips" 
     } 
  }

如果您将jni库存储在其他目录中,或者也使用外部链接的jni库,请将它们包含在应用程序的不同源代码集中。

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

答案 13 :(得分:0)

这可能是与设备相关的问题 我在仅限MI设备中收到此错误,代码正在与所有其他设备一起使用。

这可能会有所帮助:

 defaultConfig{
      ...    
      externalNativeBuild {
                    cmake {
                        cppFlags "-frtti -fexceptions"
                    }
                }
    }

答案 14 :(得分:0)

System.loadLibrarylib文件夹加载共享库。

当你说&#34;我确定&#39;例如&#39;时,你是什么意思? class存在于当前文件夹中&#34;? 您应该将.so库放到lib文件夹中。

答案 15 :(得分:0)

对我来说问题是NDK_ROOT未设置。

检查您的控制台是否:

NDK_ROOT =无 [!] NDK_ROOT未定义。请在您的环境或local.properties

中定义NDK_ROOT

检查您是否已设置:

  • C / C ++中的NDK_ROOT和SDK_ROOT - &gt; Build-&gt;环境
  • Android-&GT; NDK
  • Android-&GT; SDK

答案 16 :(得分:0)

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

答案 17 :(得分:0)

在我的情况下,在ndk-build文件夹中运行jni后,共享库在libs文件夹下创建,但是在build.gradle中指定了路径

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

所以我需要将创建的共享库移动到jnilibs文件夹中,并且可以使用!