Pendistribusian middleware yang dibangun dengan NDK memunculkan beberapa masalah tambahan yang tidak perlu dikhawatirkan oleh developer aplikasi. Library bawaan akan menerapkan beberapa pilihan implementasi mereka kepada pengguna.
Memilih API level dan versi NDK
Pengguna Anda tidak dapat menggunakan minSdkVersion yang lebih rendah dari milik Anda. Jika aplikasi pengguna perlu dijalankan di API 21, Anda tidak dapat mem-build untuk API 24. Anda dapat mem-build library untuk API level yang lebih rendah daripada pengguna Anda. Anda dapat mem-build untuk API 16 dan tetap kompatibel dengan pengguna API 21.
Sebagian besar versi NDK kompatibel satu sama lain, namun terkadang ada perubahan yang merusak kompatibilitas. Jika Anda mengetahui bahwa semua pengguna Anda menggunakan versi NDK yang sama, sebaiknya gunakan versi yang sama seperti mereka. Jika tidak, gunakan versi terbaru.
Menggunakan STL
Jika Anda menulis C++ dan menggunakan STL, pilihan antara libc++_shared
dan
libc++_static
akan memengaruhi pengguna jika Anda mendistribusikan library bersama. Jika Anda
mendistribusikan library bersama, Anda harus menggunakan libc++_shared
atau memastikan bahwa
simbol libc++ tidak diekspos oleh library. Cara terbaik untuk melakukannya adalah
mendeklarasikan permukaan ABI secara eksplisit dengan skrip versi (ini juga membantu menjaga
detail penerapan Anda tetap pribadi). Misalnya, library aritmetika sederhana
mungkin memiliki skrip versi berikut:
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:
*;
};
Skrip versi harus menjadi opsi pilihan karena merupakan cara paling efektif untuk mengontrol visibilitas simbol. Ini adalah praktik terbaik untuk semua library bersama, middleware atau bukan, karena hal ini mencegah detail implementasi Anda terekspos dan meningkatkan waktu pemuatan.
Opsi lainnya yang kurang efektif adalah menggunakan -Wl,--exclude-libs,libc++_static.a
-Wl,--exclude-libs,libc++abi.a
saat menautkan. Opsi ini kurang efektif karena
hanya akan menyembunyikan simbol di library yang diberi nama secara eksplisit, dan tidak ada
diagnostik yang dilaporkan untuk library yang tidak digunakan (salah ketik pada nama
library bukan merupakan error, dan pengguna harus
terus memperbarui daftar library). Pendekatan ini juga tidak menyembunyikan detail penerapan Anda sendiri.
Mendistribusikan library native di AAR
Plugin Android Gradle dapat mengimpor dependensi native yang didistribusikan dalam AAR. Jika pengguna menggunakan plugin Android Gradle, ini adalah cara termudah bagi mereka untuk menggunakan library Anda.
Library native dapat dipaketkan ke AAR oleh AGP. Ini akan menjadi opsi termudah jika library Anda sudah dibuat oleh externalNativeBuild.
Build Non-AGP dapat menggunakan ndkports, atau melakukan pemaketan manual dengan mengikuti
dokumentasi Prefab untuk membuat subdirektori prefab/
dari AAR-nya.
Middleware Java dengan library JNI
Library Java yang menyertakan library JNI (dengan kata lain, AAR yang berisi
jniLibs
) harus berhati-hati agar library JNI yang disertakan tidak akan
bertabrakan dengan library lain dalam aplikasi pengguna. Misalnya, jika AAR menyertakan
libc++_shared.so
, tetapi versi libc++_shared.so
yang berbeda dari yang digunakan oleh aplikasi,
hanya satu yang akan diinstal ke APK dan yang dapat mengakibatkan perilaku
yang tidak dapat diandalkan.
Solusi yang paling dapat diandalkan adalah agar library Java menyertakan tidak lebih dari satu
library JNI (ini juga saran yang bagus untuk aplikasi). Semua dependensi termasuk
STL harus ditautkan secara statis ke library implementasi, dan
skrip versi harus digunakan untuk menerapkan permukaan ABI. Misalnya, library Java
com.example.foo
yang menyertakan library JNI libfooimpl.so
harus menggunakan
skrip versi berikut:
LIBFOOIMPL {
global:
JNI_OnLoad;
local:
*;
};
Contoh ini menggunakan registerNatives
melalui JNI_OnLoad
seperti yang dijelaskan dalam Tips untuk JNI
untuk memastikan bahwa permukaan ABI minimal terekspos dan waktu pemuatan library
diminimalkan.