Saran untuk vendor middleware

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.