System.loadLibrary (…) konnte in meinem Fall keine native Bibliothek finden

Lesezeit: 8 Minuten

SystemloadLibrary konnte in meinem Fall keine native Bibliothek finden
Benutzer842225

Ich möchte eine vorhandene native Bibliothek aus verwenden Ein weiterer Android-Projekt, also habe ich einfach die von NDK erstellte Bibliothek kopiert (libcalculate.so) zu meinem neuen Android-Projekt. In meinem neuen Android-Projekt habe ich einen Ordner erstellt libs/armeabi/ und legen libcalculate.so dort. Es gibt Nein jni/ Ordner. Mein Testgerät hat eine ARM-Architektur.

In meinem Java-Code lade ich die Bibliothek durch:

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

Wenn ich mein neues Android-Projekt ausführe, bekomme ich einen Fehler:

java.lang.UnsatisfiedLinkError:  ...
nativeLibraryDirectories=[/vendor/lib, /system/lib]]] couldn't find "libcalculate.so"

Wie der Fehler sagt, befindet sich die kopierte native Bibliothek nicht in /verdor/lib oder /system/lib , wie kann ich dieses Problem in meinem Fall lösen?

(Ich habe das apk-Paket entpackt, unter lib/ gibt es libcalculate.so)

====AKTUALISIEREN=====

Ich habe auch versucht, einen jni/-Ordner im Projektstammverzeichnis zu erstellen und eine Android.mk-Datei unter jni/ hinzuzufügen. Der Inhalt von Android.mk ist:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE    := libcalculate
LOCAL_SRC_FILES := libcalculate.so
include $(PREBUILT_SHARED_LIBRARY)

Dann habe ich unter Projektstamm ndk-build ausgeführt. Danach werden die Verzeichnisse armeabi/ und armeabi-v7a/ von ndk-build generiert (mit libcalculate.so im Ordner).

Dann führe ich mein Maven-Build-Projekt erfolgreich aus. Im endgültigen apk-Paket gibt es:

lib/armeabi/libcalculate.so
lib/armeabi-v7a/libcalculate.so

Aber wenn ich meine App starte, wird der gleiche Fehler ausgelöst:

java.lang.UnsatisfiedLinkError:  ...
nativeLibraryDirectories=[/vendor/lib, /system/lib]]] couldn't find "libcalculate.so"

  • Sie legen die Bibliothek direkt unter libs/? Sie müssen wahrscheinlich ein Unterverzeichnis pro Ziel-ABI erstellen, das Sie unterstützen möchten (armeabi, armeabi-v7a, x86, mips usw.) und die entsprechende .so-Datei in jedem Unterverzeichnis ablegen (d. h. die für armeabi erstellte .so-Datei kommt hinein libs/armeabi/etc).

    – Michael

    11. Dezember 14 um 11:28 Uhr


  • @Michael, das habe ich gerade in meinem Beitrag übersehen, ich habe es tatsächlich unter libs/armeabi/ abgelegt

    – Benutzer842225

    11. Dezember 14 um 11:43 Uhr

  • Überprüfen Sie, ob libcalculate.so tatsächlich vom Paketierungsprozess abgeholt wird – versuchen Sie es zB unzip -l package.apk, oder benennen Sie die apk in .zip um und öffnen Sie sie mit einer Anwendung. Wenn es nicht da ist, stimmt etwas mit dem Packen nicht (hat Ihre IDE bemerkt, dass der Ordner dort ist, müssen Sie das Projekt aktualisieren?).

    – mstorsjo

    11. Dezember 14 um 14:31 Uhr

  • @mstorsjo, ich habe das apk-Paket entpackt, unter lib/ gibt es libcalculate.so

    – Benutzer842225

    11. Dezember 14 um 18:41 Uhr

  • Sie brauchen keine Android.mk oder andere kompilierungsbezogene Dateien. Legen Sie einfach die so-Dateien in die entsprechenden Unterverzeichnisse von jniLibs wie hier: github.com/Ph1b/MaterialAudiobookPlayer/tree/master/audiobook/…

    – Paul Woitaschek

    15. Dezember 14 um 10:36 Uhr

1643911390 80 SystemloadLibrary konnte in meinem Fall keine native Bibliothek finden
ph0b

Um der Ursache auf den Grund zu gehen (und vielleicht gleichzeitig Ihr Problem zu lösen), können Sie Folgendes tun:

  1. Entfernen Sie den jni-Ordner und alle .mk Dateien. Sie brauchen weder diese noch das NDK, wenn Sie nichts kompilieren.

  2. Kopieren Sie Ihre libcalculate.so Datei drin <project>/libs/(armeabi|armeabi-v7a|x86|...) . Bei Verwendung von Android Studio ist es <project>/app/src/main/jniLibs/(armeabi|armeabi-v7a|x86|...)aber ich sehe, Sie verwenden Eclipse.

  3. Erstellen Sie Ihr APK und öffnen Sie es als zip-Dateium zu überprüfen, ob Ihre libcalculate.so Datei ist drin lib/(armeabi|armeabi-v7a|x86|…).

  4. Entfernen und installieren Sie Ihre Anwendung

  5. Lauf dumpsys Paket Pakete | grep IhrPaketname um das zu bekommen nativeLibraryPath oder LegacyNativeLibraryDir Ihrer Bewerbung.

  6. Lauf ls auf der nativeLibraryPath Sie hatten oder auf legacyNativeLibraryDir/armeabium zu überprüfen, ob Ihre libcalculate.so tatsächlich vorhanden ist.

  7. Wenn es dort ist, überprüfen Sie, ob es nicht von Ihrem Original geändert wurde libcalculate.so Datei: ist sie gegen die richtige Architektur kompiliert, enthält sie die erwarteten Symbole, gibt es fehlende Abhängigkeiten. Sie können libcalculate.so mit readelf analysieren.

Um Schritt 5-7 zu überprüfen, können Sie meine Anwendung anstelle von Befehlszeilen und readelf verwenden: Native Libs-Monitor

PS: Es ist leicht, verwirrt zu werden, wo .so-Dateien standardmäßig abgelegt oder generiert werden sollten, hier ist eine Zusammenfassung:

  • libs/CPU_ABI innerhalb eines Eclipse-Projekts

  • jniLibs/CPU_ABI innerhalb eines Android Studio-Projekts

  • jni/CPU_ABI in einem AAR

  • lib/CPU_ABI in der endgültigen APK

  • innerhalb der App nativeLibraryPath auf einem <5.0-Gerät und in der App LegacyNativeLibraryDir/CPU_ARCH auf einem >=5.0 Gerät.

Wo CPU_ABI ist einer von: armeabi, armeabi-v7a, arm64-v8a, x86, x86_64, mips, mips64. Abhängig davon, auf welche Architekturen Sie abzielen und für welche Bibliotheken kompiliert wurden.

Beachten Sie auch, dass Bibliotheken nicht zwischen CPU_ABI-Verzeichnissen gemischt werden: Sie benötigen den vollständigen Satz dessen, was Sie verwenden, eine Bibliothek, die sich in der befindet armabi Ordner wird nicht auf einem installiert armeabi-v7a Gerät, wenn sich Bibliotheken darin befinden armeabi-v7a Ordner aus der APK.

  • Toller Mann, danke! Ich verwende Android Studio und meine jni-Builds wurden in libs statt in jniLibs kopiert.

    – Luis

    17. Dezember 14 um 17:59 Uhr

  • Der letzte Hinweis, dass ich das komplette Set benötigte, war für mich entscheidend. Das war mein Problem, danke!

    – Ben Trengrove

    20. Mai ’15 um 14:18 Uhr

  • Für die 7 Abschnitt: Meinen Sie damit, dass die .so-Datei möglicherweise von der APK geändert wird, nachdem sie auf dem Gerät installiert wurde? Wenn ja, besteht die Möglichkeit, dass das System die .so-Datei ruiniert?

    – Jayatubi

    3. Oktober 15 um 5:55 Uhr

  • Wunderbar! In meinem sehr seltsamen Fall habe ich einen Satz von Bibliotheken eines Drittanbieters verwendet (OpenCV – in der armabi Ordner) und diese Bibliotheken wurden nicht mehr geladen, als ich über Gradle eine andere Bibliothek eines Drittanbieters hinzufügte. Es stellt sich heraus, dass die zweite Bibliothek ARMv5 oder 6 nicht unterstützt, und durch das Einfügen wurden meine OpenCV-Bibliotheken unsichtbar (obwohl sie waren tatsächlich da). Ihr Punkt zum vollständigen Satz gab mir den Hinweis – den Armabi-Ordner umzubenennen und ihn aufzurufen armeabi-v7a das Problem behoben (da ich jetzt ARM 5 oder 6 nicht mehr unterstütze …). Böses Problem!!

    – Met

    4. November 15 um 13:56 Uhr

  • Eine andere Möglichkeit, um herauszufinden, wo Sie Ihre lib-Datei (*.so) ablegen können, besteht darin, Ihre Anwendung auszuführen und das nativeLibraryDir zu drucken, indem Sie Folgendes verwenden: System.out.println(getApplicationContext().getApplicationInfo().nativeLibraryDir), der Name des Verzeichnisses wird ebenfalls angezeigt Ihnen das ABI ausstellen.

    – David Rauca

    10. Juni 17 um 17:00 Uhr

SystemloadLibrary konnte in meinem Fall keine native Bibliothek finden
Mukund Muralikrishnan

In Gradle, nachdem Sie alle Dateien in Ordner kopiert haben libs/

jniLibs.srcDirs = ['libs']

Hinzufügen der obigen Zeile zu sourceSets in build.gradle Datei hat funktioniert. Nichts anderes hat funktioniert.

  • Wo befindet sich “sourceSets” in der Datei build.gradle?

    – Ashana.Jackol

    16. Juni 16 um 6:09 Uhr

  • @Ashana.Jackol In deinem build.gradle

    – Olajid

    29. November 2020 um 12:56 Uhr

In meinem Fall muss ich das Kompilieren von Quellen durch Gradle ausschließen und den Libs-Pfad festlegen

android {

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

  • Dies löste sich auch für mich und ich fügte die Dateien von Armeabi in den Ordnern Armeabi-v7a und x86 hinzu, aber ich bin mir nicht sicher, ob es notwendig war.

    – dokam_schottland

    24. Mai 19 um 10:44 Uhr

Der Grund für diesen Fehler liegt darin, dass die ABI zwischen Ihrer App und der nativen Bibliothek, mit der Sie verknüpft sind, nicht übereinstimmt. Mit anderen Worten, Ihre App und Ihre .so zielt auf einen anderen ABI ab.

Wenn Sie Ihre App mit den neuesten Android Studio-Vorlagen erstellen, zielt sie wahrscheinlich auf die arm64-v8a aber dein .so kann zielgerichtet sein armeabi-v7a zum Beispiel.

Es gibt zwei Möglichkeiten, dieses Problem zu lösen:

  1. Erstellen Sie Ihre nativen Bibliotheken für jede ABI, die Ihre App unterstützt.
  2. Ändern Sie Ihre App so, dass sie auf ältere ABI abzielt, die Ihre sind .so dagegen gebaut.

Wahl 2 ist schmutzig, aber ich denke, Sie interessieren sich wahrscheinlich mehr für:

ändern Sie Ihre App build.gradle

android {
    defaultConfig {
        ...
        ndk {
            abiFilters 'armeabi-v7a'
        }
   }
}

Benutzt du Gradle? Wenn ja, setzen Sie die .so Datei in <project>/src/main/jniLibs/armeabi/

Ich hoffe, es hilft.

  • Nein, ich verwende kein Gradle, ich verwende Eclipse + Maven

    – Benutzer842225

    15. Dezember 14 um 16:07 Uhr

1643911391 431 SystemloadLibrary konnte in meinem Fall keine native Bibliothek finden
Andy Krouwel

Als Referenz hatte ich diese Fehlermeldung und die Lösung war, dass Sie beim Angeben der Bibliothek das ‘lib’ vorne und das ‘.so’ am Ende verpassen.

Wenn Sie also eine Datei libmyfablib.so haben, müssen Sie Folgendes aufrufen:

   System.loadLibrary("myfablib"); // this loads the file 'libmyfablib.so' 

Nachdem ich in die apk geschaut, installiert/deinstalliert und alle möglichen komplexen Lösungen ausprobiert hatte, konnte ich das einfache Problem nicht sehen, das direkt vor meinem Gesicht lag!

  • Nein, ich verwende kein Gradle, ich verwende Eclipse + Maven

    – Benutzer842225

    15. Dezember 14 um 16:07 Uhr

Dies ist ein Android 8-Update.

In früheren Versionen von Android habe ich meinen nativen Code zu LoadLibrary nativen gemeinsam genutzten Bibliotheken (z. B. für den Zugriff über JNI) fest verdrahtet, um eine Reihe potenzieller Verzeichnispfade für den lib-Ordner zu durchlaufen, basierend auf den verschiedenen apk-Installations-/Upgrade-Algorithmen:

/data/data/<PackageName>/lib
/data/app-lib/<PackageName>-1/lib
/data/app-lib/<PackageName>-2/lib
/data/app/<PackageName>-1/lib
/data/app/<PackageName>-2/lib

Dieser Ansatz ist heikel und funktioniert nicht für Android 8; von https://developer.android.com/about/versions/oreo/android-8.0-changes.html
Sie werden sehen, dass Sie als Teil ihrer “Sicherheits”-Änderungen jetzt sourceDir verwenden müssen:

“Sie können nicht länger davon ausgehen, dass sich APKs in Verzeichnissen befinden, deren Namen auf -1 oder -2 enden. Apps sollten sourceDir verwenden, um das Verzeichnis abzurufen, und sich nicht direkt auf das Verzeichnisformat verlassen.”

Korrektur, sourceDir ist nicht der Weg, um Ihre nativen gemeinsam genutzten Bibliotheken zu finden; benutze sowas wie. Getestet für Android 4.4.4 –> 8.0

// Return Full path to the directory where native JNI libraries are stored.
private static String getNativeLibraryDir(Context context) {
    ApplicationInfo appInfo = context.getApplicationInfo();
    return appInfo.nativeLibraryDir;
}

.

758410cookie-checkSystem.loadLibrary (…) konnte in meinem Fall keine native Bibliothek finden

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy