Consulenza per fornitori di middleware

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.