System.loadLibrary (…) konnte in meinem Fall keine native Bibliothek finden
Lesezeit: 8 Minuten
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:
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:
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
Um der Ursache auf den Grund zu gehen (und vielleicht gleichzeitig Ihr Problem zu lösen), können Sie Folgendes tun:
Entfernen Sie den jni-Ordner und alle .mk Dateien. Sie brauchen weder diese noch das NDK, wenn Sie nichts kompilieren.
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.
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|…).
Entfernen und installieren Sie Ihre Anwendung
Lauf dumpsys Paket Pakete | grep IhrPaketname um das zu bekommen nativeLibraryPath oder LegacyNativeLibraryDir Ihrer Bewerbung.
Lauf ls auf der nativeLibraryPath Sie hatten oder auf legacyNativeLibraryDir/armeabium zu überprüfen, ob Ihre libcalculate.so tatsächlich vorhanden ist.
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
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
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:
Erstellen Sie Ihre nativen Bibliotheken für jede ABI, die Ihre App unterstützt.
Ä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:
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
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:
“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;
}
.
7584100cookie-checkSystem.loadLibrary (…) konnte in meinem Fall keine native Bibliothek findenyes
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 hineinlibs/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