Sebelum memulai
Panduan ini berasumsi bahwa Anda telah memahami berbagai konsep yang ada dalam pemrograman native dan dalam pengembangan Android.
Pengantar
Bagian ini menyediakan penjelasan tingkat tinggi mengenai cara kerja NDK. Android NDK adalah sekumpulan alat yang memungkinkan Anda menyematkan kode C atau C++ (“kode native”) ke dalam aplikasi Android Anda. Kemampuan untuk menggunakan kode native di aplikasi Android bisa sangat berguna bagi developer yang ingin melakukan salah satu atau beberapa hal berikut:
- Mengadaptasikan aplikasi di berbagai platform.
- Menggunakan kembali library yang sudah ada, atau menyediakan library mereka sendiri untuk digunakan kembali.
- Meningkatkan performa dalam kasus tertentu, terutama pada aplikasi yang sarat komputasi seperti game.
Cara kerjanya
Bagian ini memperkenalkan berbagai komponen utama yang digunakan dalam mem-build aplikasi native untuk Android, dan dilanjutkan dengan menjelaskan proses build dan pemaketan.
Komponen utama
Anda harus memiliki pemahaman mengenai komponen berikut saat mem-build aplikasi:
Library bersama native: NDK mem-build library ini, atau file
.so
, dari kode sumber C/C++.Library statis native: NDK juga dapat mem-build library statis, atau file
.a
, yang dapat ditautkan ke library lain.Java Native Interface (JNI): JNI adalah antarmuka bagi komponen Java dan C++ untuk saling berkomunikasi. Panduan ini berasumsi bahwa Anda telah memahami JNI; untuk mengetahui informasi tentang JNI, lihat Spesifikasi Java Native Interface.
Application Binary Interface (ABI): ABI menentukan secara pasti bagaimana kode mesin aplikasi Anda diharapkan berinteraksi dengan sistem pada runtime. NDK mem-build file
.so
berdasarkan definisi ini. ABI yang berbeda berkaitan dengan arsitektur yang berbeda: NDK menyertakan dukungan ABI untuk ARM 32-bit, AArch64, x86, dan x86-64. Untuk informasi selengkapnya, lihat ABI Android.Manifes: Jika menulis aplikasi tanpa komponen Java, Anda harus mendeklarasikan class NativeActivity dalam manifes. Lihat Menggunakan antarmuka native_activity.h untuk detail selengkapnya tentang cara melakukannya.
Alur
Alur umum untuk mengembangkan aplikasi native Android adalah seperti berikut:
Desain aplikasi Anda, tentukan bagian mana saja yang akan diimplementasikan di Java, dan bagian mana yang akan diimplementasikan sebagai kode native.
Buat Project aplikasi Android seperti yang Anda lakukan untuk project Android lainnya.
Jika Anda menulis aplikasi khusus native, deklarasikan class NativeActivity dalam
AndroidManifest.xml
. Untuk informasi selengkapnya, lihat Aktivitas dan aplikasi native.Buat file
Android.mk
yang mendeskripsikan library native, termasuk nama, flag, library tertaut, dan file sumber yang akan dikompilasi dalam direktori "JNI".Anda juga dapat membuat file
Application.mk
yang mengonfigurasi ABI target, toolchain, mode rilis/debug, dan STL. Untuk semua elemen ini yang tidak Anda tentukan, nilai default berikut akan digunakan:- ABI: semua ABI yang masih digunakan
- Mode: Release
- STL: system
Tempatkan sumber native Anda dalam direktori
jni
project.Gunakan ndk-build untuk mengompilasi library native (
.so
,.a
).Build komponen Java, yang akan menghasilkan file executable
.dex
.Paketkan semuanya ke dalam file APK, berisi
.so
,.dex
, serta file lain yang diperlukan untuk menjalankan aplikasi.
Aktivitas dan aplikasi native
Android SDK menyediakan class helper, NativeActivity, yang memungkinkan Anda
menulis aktivitas yang sepenuhnya native. NativeActivity menangani komunikasi
antara framework Android dan kode native, sehingga Anda tidak perlu membuat
subclass untuknya atau memanggil metodenya. Anda hanya perlu mendeklarasikan aplikasi
sebagai native dalam file AndroidManifest.xml
, lalu mulai membuat aplikasi
native.
Aplikasi Android yang menggunakan NativeActivity tetap berjalan di mesin virtualnya sendiri, yang di-sandbox dari aplikasi lain. Oleh karena itu, Anda masih dapat mengakses API framework Android melalui JNI. Dalam kasus tertentu, seperti untuk sensor, peristiwa input, dan aset, NDK menyediakan antarmuka native yang dapat Anda gunakan sehingga tidak perlu memanggil melalui JNI. Untuk informasi selengkapnya tentang dukungan tersebut, lihat API native.
Baik Anda sedang mengembangkan aktivitas native atau tidak, sebaiknya Anda membuat project dengan alat build Android tradisional. Ini akan membantu memastikan pembuatan dan pemaketan aplikasi Android dengan struktur yang benar.
Android NDK memberikan dua pilihan untuk mengimplementasikan aktivitas native:
- Header native_activity.h menentukan versi native class NativeActivity. Class ini berisi antarmuka callback dan struktur data yang Anda perlukan untuk membuat aktivitas native. Karena thread utama aplikasi Anda menangani callback, implementasi callback Anda tidak boleh memblokir. Jika memblokir, Anda mungkin akan menerima error ANR (Aplikasi Tidak Merespons) karena thread utama tidak merespons hingga callback tersebut kembali.
- File
android_native_app_glue.h
menentukan library bantuan statis yang dibuat di atas antarmuka native_activity.h. File ini menghasilkan thread lain, yang menangani hal-hal seperti callback atau peristiwa input dalam suatu loop peristiwa. Memindahkan peristiwa ini ke thread terpisah akan mencegah callback memblokir thread utama Anda.
Sumber <ndk_root>/sources/android/native_app_glue/android_native_app_glue.c
juga tersedia, yang memungkinkan Anda memodifikasi implementasi.
Untuk mengetahui informasi selengkapnya tentang cara menggunakan library statis ini, periksa
aplikasi contoh aktivitas native dan dokumentasinya. Bacaan lebih lanjut
juga tersedia di komentar dalam
file <ndk_root>/sources/android/native_app_glue/android_native_app_glue.h
.
Menggunakan antarmuka native_activity.h
Untuk mengimplementasikan aktivitas native dengan antarmuka native_activity.h:
Buat direktori
jni/
dalam direktori utama project Anda. Direktori ini menyimpan semua kode native Anda.Deklarasikan aktivitas native Anda dalam file
AndroidManifest.xml
.Karena aplikasi Anda tidak memiliki kode Java, tetapkan
android:hasCode
kefalse
.<application android:label="@string/app_name" android:hasCode="false">
Anda harus menetapkan atribut
android:name
tag aktivitas ke NativeActivity.<activity android:name="android.app.NativeActivity" android:label="@string/app_name">
Atribut
android:value
tagmeta-data
menentukan nama library bersama yang berisi titik entri ke aplikasi (sepertimain
C/C++), dengan menghilangkan awalanlib
dan akhiran.so
dari nama library.<manifest> <application> <activity> <meta-data android:name="android.app.lib_name" android:value="native-activity" /> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
Buat file untuk aktivitas native Anda, dan implementasikan fungsi yang dinamai dalam variabel ANativeActivity_onCreate. Aplikasi memanggil fungsi ini saat aktivitas native dimulai. Fungsi ini, yang serupa dengan
main
di C/C++, menerima pointer ke struktur ANativeActivity, yang berisi pointer fungsi ke berbagai implementasi callback yang perlu Anda tulis. Tetapkan pointer fungsi callback yang berlaku diANativeActivity->callbacks
ke implementasi callback Anda.Tetapkan kolom
ANativeActivity->instance
ke alamat instance data tertentu yang ingin Anda gunakan.Implementasikan semua hal lainnya yang Anda ingin aktivitas lakukan saat memulai.
Implementasikan callback lain yang ditetapkan di
ANativeActivity->callbacks
. Untuk mengetahui informasi selengkapnya tentang kapan callback dipanggil, lihat Mengelola Siklus Proses Aktivitas.Kembangkan bagian lain aplikasi.
Buat
Android.mk file
dalam direktorijni/
project untuk mendeskripsikan modul native ke sistem build. Untuk informasi selengkapnya, lihat Android.mk.Setelah Anda memiliki file Android.mk, kompilasikan kode native menggunakan perintah
ndk-build
.cd <path>/<to>/<project> $NDK/ndk-build
Buat dan instal project Android Anda seperti biasa. Jika kode native Anda berada dalam direktori
jni/
, skrip build akan otomatis memaketkan file.so
yang dibuat darinya ke dalam APK.
Kode contoh tambahan
Untuk mendownload contoh NDK, lihat Contoh NDK.