La distribuzione del middleware creato con l'NDK solleva alcuni problemi aggiuntivi che gli sviluppatori di app non devono preoccuparsi. Le librerie predefinite impongono le scelte di implementazione per gli utenti.
Scelta dei livelli API e delle versioni NDK
I tuoi utenti non possono utilizzare un valore minSdkVersion inferiore al tuo. Se i tuoi utenti app devono essere eseguiti sull'API 21, non puoi creare per l'API 24. Puoi creare il tuo libreria per un livello API inferiore rispetto a quello dei tuoi utenti. Puoi creare contenuti per le API 16 e la compatibilità con gli utenti dell'API 21.
Le versioni NDK sono ampiamente compatibili tra loro, ma a volte ci sono modifiche che interrompono la compatibilità. Se sai che tutti i tuoi utenti utilizzano della stessa versione dell'NDK, è meglio usarne la stessa versione. In caso contrario, utilizza la versione più recente.
Utilizzo dell'STL
Se scrivi in C++ e utilizzi il linguaggio STL, puoi scegliere tra libc++_shared
e
La distribuzione di una libreria condivisa influisce su libc++_static
. Se
distribuire una libreria condivisa, devi usare libc++_shared
o assicurarti che
I simboli di libc++ non sono esposti nella tua raccolta. Il modo migliore per farlo è
dichiarare esplicitamente la piattaforma ABI con uno script di versione (questo aiuta anche a
i dettagli dell'implementazione privati). Ad esempio, una semplice libreria aritmetica
potrebbe avere il seguente script di versione:
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:
*;
};
Uno script di versione dovrebbe essere l'opzione preferita perché è la versione più robusta per controllare la visibilità dei simboli. Questa è una best practice per tutti i contenuti condivisi librerie, middleware o meno, in quanto impedisce ai dettagli di implementazione dei carichi di lavoro e riduce i tempi di caricamento.
Un'altra opzione meno efficace è quella di utilizzare -Wl,--exclude-libs,libc++_static.a
-Wl,--exclude-libs,libc++abi.a
per il collegamento. Questo sistema è meno affidabile perché
nasconderà solo i simboli nelle librerie con nomi espliciti e non
vengono segnalate le informazioni di diagnostica per le librerie che non vengono utilizzate (un errore di battitura nella libreria
nome non è un errore e l'utente deve mantenere l'elenco delle biblioteche
alla data corrente). Inoltre, questo approccio non nasconde i tuoi dettagli di implementazione.
Distribuzione di librerie native nei AAR
Il plug-in Android per Gradle può importare dipendenze native distribuite AAR. Se i tuoi utenti utilizzano il plug-in Android Gradle, questa sarà la il modo più semplice per usare la tua raccolta.
Le librerie native possono essere pacchettizzate in un file AAR AGP. Questa sarà la l'opzione più semplice se la libreria è già creata da external NativeBuild.
Le build non AGP possono utilizzare ndkports o eseguire il pacchettizzazione manuale seguendo le istruzioni
Documentazione Prefab per creare la sottodirectory prefab/
del relativo AAR.
middleware Java con librerie JNI
librerie Java che includono librerie JNI (in altre parole, AAR che contengono
jniLibs
) devi prestare attenzione che le librerie JNI che includono non
sono in conflitto con altre librerie nell'app dell'utente. Ad esempio, se l'AAR include
libc++_shared.so
, ma una versione di libc++_shared.so
diversa da quella dell'app
ne verrà installata solo una, pertanto l'APK potrebbe
comportamento degli utenti.
La soluzione più affidabile è che le librerie Java includano non più di un
nella libreria JNI (questo è un buon consiglio anche per le app). Tutte le dipendenze, incluso il
L'STL deve essere collegato in modo statico alla libreria di implementazione e una versione
utilizzare lo script per applicare la piattaforma ABI. Ad esempio, una libreria Java
com.example.foo
che include la libreria JNI libfooimpl.so
deve usare il metodo
il seguente script di versione:
LIBFOOIMPL {
global:
JNI_OnLoad;
local:
*;
};
Questo esempio utilizza registerNatives
tramite JNI_OnLoad
come descritto nei suggerimenti di JNI
per garantire che la superficie ABI minima sia esposta e che il tempo di caricamento della libreria sia
ridotto a icona.