Die Verteilung von Middleware, die mit dem NDK erstellt wurde, wirft einige zusätzliche Probleme auf, müssen sich App-Entwickler keine Gedanken machen. Vordefinierte Bibliotheken bei der Implementierung an ihre Nutzenden aus.
API-Ebenen und NDK-Versionen auswählen
Ihre Nutzer dürfen keine niedrigere minSdkVersion als Ihre verwenden. Wenn die Apps auf API 21 ausgeführt werden müssen, können Sie nicht für API 24 erstellen. Es ist in Ordnung, für ein niedrigeres API-Level als Ihre Nutzer. Sie können für API erstellen 16 und bleiben mit Ihren API-21-Nutzern kompatibel.
NDK-Versionen sind weitgehend kompatibel. Gelegentlich gibt es jedoch die die Kompatibilität beeinträchtigen. Wenn Sie wissen, dass alle Ihre Nutzer NDK-Version verwenden, ist es am besten, dieselbe Version wie diese zu verwenden. Verwenden Sie andernfalls die neueste Version.
STL verwenden
Wenn Sie in C++ schreiben und STL verwenden, haben Sie die Wahl zwischen libc++_shared
und
libc++_static
wirkt sich auf Ihre Nutzer aus, wenn Sie eine gemeinsam genutzte Bibliothek verteilen. Wenn Sie
eine gemeinsam genutzte Bibliothek bereitstellen möchten, müssen Sie entweder libc++_shared
verwenden oder sicherstellen,
Die Symbole von libc++ werden von Ihrer Bibliothek nicht offengelegt. Am besten tun Sie dies,
die ABI-Oberfläche
explizit mit einem Versionsskript deklarieren.
Ihre Implementierungsdetails privat). Eine einfache arithmetische Bibliothek
hat möglicherweise das folgende Versionsskript:
LIBMYMATH {
global:
add;
sub;
mul;
div;
# C++ symbols in an extern block will be mangled automatically. See
# https://stackoverflow.com/a/21845178/632035 for more examples.
extern "C++" {
"pow(int, int)";
}
local:
*;
};
Ein Versionsskript sollte die bevorzugte Option sein, da es die zuverlässigste die Sichtbarkeit von Symbolen. Dies ist eine Best Practice für alle gemeinsam genutzten Middleware oder nicht, da die Implementierungsdetails und die Ladezeit verkürzt.
Eine weitere, weniger zuverlässige Option ist die Verwendung von -Wl,--exclude-libs,libc++_static.a
-Wl,--exclude-libs,libc++abi.a
für die Verknüpfung. Dies ist weniger zuverlässig,
werden in den Bibliotheken nur die explizit benannten Symbole ausgeblendet.
Diagnosedaten werden für nicht verwendete Bibliotheken ausgegeben (ein Tippfehler in der Bibliothek).
Der Name ist kein Fehler und es liegt in der Verantwortung des Nutzers, die Bibliotheksliste aktiv zu halten.
bis heute). Dabei werden auch Ihre eigenen Implementierungsdetails nicht verborgen.
Native Bibliotheken in AAE verteilen
Das Android-Gradle-Plug-in kann native Abhängigkeiten importieren, die AAE: Wenn Ihre Nutzer das Android-Gradle-Plug-in verwenden, ist dies der die beste Möglichkeit, Ihre Bibliothek zu nutzen.
Native Bibliotheken lassen sich in automatisch angewendete Empfehlungen AGP Dies ist der Dies ist die einfachste Option, wenn Ihre Bibliothek bereits von externalNativeBuild erstellt wurde.
Nicht-AGP-Builds können ndkports verwenden oder manuelles Packen durchführen, indem sie der
Prefab-Dokumentation, um das Unterverzeichnis prefab/
des AAE zu erstellen.
Java-Middleware mit JNI-Bibliotheken
Java-Bibliotheken, die JNI-Bibliotheken enthalten (d. h. AARs, die
jniLibs
) müssen darauf achten, dass die darin enthaltenen JNI-Bibliotheken keine
mit anderen Bibliotheken
in der App kollidieren. Wenn in den automatisch angewendeten Empfehlungen beispielsweise
libc++_shared.so
, aber eine andere Version von libc++_shared.so
als die App
verwendet wird, wird nur eines im APK installiert. Dies kann zu unzuverlässigen
verhalten.
Die zuverlässigste Lösung ist, wenn Java-Bibliotheken nur eine enthalten.
JNI-Bibliothek (auch für Apps geeignet) Alle Abhängigkeiten, einschließlich der
STL sollte statisch mit der Implementierungsbibliothek verknüpft sein und eine Version
Script sollte verwendet werden, um die ABI-Oberfläche zu erzwingen. Eine Java-Bibliothek
com.example.foo
, die die JNI-Bibliothek libfooimpl.so
enthält, sollte die Methode
folgendes Versionsskript:
LIBFOOIMPL {
global:
JNI_OnLoad;
local:
*;
};
In diesem Beispiel wird registerNatives
über JNI_OnLoad
verwendet, wie in den JNI-Tipps beschrieben.
um sicherzustellen, dass die minimale ABI-Oberfläche sichtbar ist und die Bibliotheksladezeit
werden minimiert.