web-dev-qa-db-fra.com

java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader

Y a-t-il quelqu'un qui a eu l'expérience de cette erreur?

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"

Une erreur se produit lorsque je charge la bibliothèque de cette manière.

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

Je suis sûr que la classe "exemple" existe dans le dossier actuel.

48
developergg

Veuillez noter qu'il existe une convention de nommage. Votre lib doit s'appeler libexample.so.

LoadLibrary ("example") recherchera libexample.so.

La bibliothèque .so doit être dans l'apk sous le dossier lib (puisque vous développez pour Android, elle doit se trouver sous les dossiers lib/armeabi et lib/armeabi-v7a - pourquoi les deux dossiers? Quelques versions de Android regardez sous lib/armeabi et certains sous lib/armeabi-v7a ... voyez ce qui vous convient).

Autres choses à rechercher:

  • assurez-vous de compiler pour une architecture correcte (si vous compilez pour armeabi v5, cela ne fonctionnera pas sur armeabiv7 ou armeabiv7s).

  • assurez-vous que vos prototypes exportés sont utilisés dans la classe correcte (consultez l'exemple hello jni. Vos fonctions exposées doivent ressembler à Java_mypackagename_myjavabridgeclass_myfunction).

Par exemple, la fonction Java_com_example_sample_hello sera traduite dans la Java classe com.example.sample, fonction hello.

45
MichaelCMS

Cela m'a aidé. Partager pour quelqu'un qui pourrait avoir le même problème.

Android {
    ....
    defaultConfig {
        ....
        ndk {
            abiFilters "armeabi", "armeabi-v7a", "x86", "mips"
        }
    }
}
25
Alex

Je travaille actuellement sur une application Android qui diffuse la radio en continu. J'utilise une bibliothèque de décodeurs native appelée aacdecoder. Tout allait bien jusqu'à ce que l'application obtienne une erreur de plantage sur certains appareils Android. C'était vraiment énervant. Parce que l'application jouait parfaitement, la radio diffusait presque tous les appareils, à l'exception des Samsung S6 et S6 Edge.

Le rapport d'accident dit que

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)

Comme vous le voyez, cet incident indique qu’il ne pourrait pas charger la bibliothèque native. Mais pourquoi? Tout d’abord, j’ai vérifié dans ma structure, si les fichiers .so de la bibliothèque native se trouvaient correctement.

On dirait que tout allait bien sauf cette erreur folle. Après quelques recherches, je découvre que certains appareils Android sont dotés de processeurs 64 bits. Ce périphérique génère et vérifie le dossier arm64 pour charger la bibliothèque native. C'était le problème. Parce que mon projet n'a pas de dossier arm64. Voici la solution.

defaultConfig {
    ...

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

}

Vous devez ajouter ces filtres (abiFilters) aux fichiers build.gradle de votre module d'application. Ainsi, lorsque votre appareil essaie d'exécuter votre application, il vérifie le fichier de niveaux et comprend qu'il ne doit pas générer de dossier ni utiliser les ressources de la bibliothèque native existante. Boom, presque résolu. Mais il reste encore une chose.

Android.useDeprecatedNdk=true

Ajoutez cette ligne à votre fichier gradle.properties pour utiliser un Ndk obsolète.

Enfin, mon application fonctionne sur S6 et S6 Edge. Je veux dire que cela fonctionne sur tous les appareils équipés de nouveaux processeurs 64 bits.

20
King of Masses

Ce qui a fonctionné pour moi a été de placer le dossier jniLibs () sous le dossier "principal", juste à côté des fichiers "Java" et " res "dossiers, par exemple projet -> application -> src -> main -> jniLibs

J'avais toutes les bibliothèques avec les noms corrects et chacune d'entre elles était placée dans leur sous-dossier d'architecture respectif, mais j'avais toujours la même exception; même essayé beaucoup d’autres SO réponses comme la réponse acceptée ici, compiler un fichier JAR avec les bibliothèques .so, placer le dossier jniLibs, etc.).

Pour ce projet, je devais utiliser Gradle 2.2 et Android Plugin 1.1.0 sur Android Studio 1.5.1

10

-if gradle.properties non disponible, ajoutez d'abord ce fichier et ajoutez Android.useDeprecatedNdk=true

-utiliser ce code dans build.gradle

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

`

8
Sanket Sangani

J'utilise Android Studio 3.0 et rencontre ce problème. Et je suis sûr que build.gradle de l'application est OK.

Allez dans Exécuter -> Modifier les configurations -> Profilage, et désactivez "Activer le profilage avancé".

Cela fonctionne pour moi. Réponse de référence

7
Smiles

C'est travaillé pour moi

Si vous avez un fichier .so dans armeabi, mentionnez alors dans ndk uniquement ce dossier.

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

et ensuite utiliser cette

Android.useDeprecatedNdk=true;

dans le fichier gradle.properties

6
KCN

Certains anciens outils de classement ne peuvent pas copier les fichiers .so dans le dossier de construction, mais une copie manuelle de ces fichiers dans le dossier de construction décrit ci-dessous peut résoudre le problème:

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

construire config: beta/production/sit/uat

architecture de support: armeabi/armeabi-v7a/mips/x86

5
thanhbinh84

Si vous utilisez Android studio, modifiez simplement le fichier gradle.properties dans le dossier racine et ajoutez Android.useDeprecatedNdk = true. Modifiez ensuite le fichier build.gradle dans le dossier de votre application, définissez abiFilters comme suit: :

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

Ce qui m'a aidé, c'est d'enregistrer le répertoire source pour les fichiers jni dans le fichier build.gradle. Ajoutez ceci à votre fichier de classement:

Android {
    sourceSets {
        main {
            jniLibs.srcDir '[YOUR_JNI_DIR]' // i.e. 'libs'
        }
    }
}
3
Boris Gitlin

Si vous utilisez le module avec du code c ++ et avez le même problème, vous pouvez essayer

Build -> Refresh Linked C++ Projects

En outre, vous devriez ouvrir un fichier de ce module et faire

Build -> Make module "YourNativeLibModuleName"

2
Sergei Belozerov

Une autre cause de crash et une solution possible sont décrites dans cet article: https://medium.com/keepsafe-engineering/the-perils-of-loading-native-libraries-on-Android-befa49dce2db

En bref:
dans build.gradle

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

dans du code

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

System.loadLibrary charge une bibliothèque partagée à partir du dossier lib.

Que voulez-vous dire en disant "je suis sûr que la classe" exemple "existe dans le dossier actuel"? Vous devriez placer votre bibliothèque .so dans le dossier lib.

0
Suvitruf

Cela pourrait être un problème lié au périphérique.
J'avais cette erreur dans périphériques MI uniquement, le code fonctionnait avec tous les autres périphériques.

Cela pourrait aider:

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

Pour moi, le problème était dans NDK_ROOT non défini.

Vérifiez votre console si:

NDK_ROOT = Aucun [!] NDK_ROOT non défini. Veuillez définir NDK_ROOT dans votre environnement ou dans le fichier local.properties

Vérifiez si vous avez défini:

  • NDK_ROOT et SDK_ROOT en C/C++ -> Construire-> Environnement
  • Android-> NDK
  • Android-> SDK
0
Iris Veriris