Konsep

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 mendefinisikan secara pasti interaksi kode mesin aplikasi dengan sistem pada runtime yang diharapkan. NDK membuat 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. Untuk detail selengkapnya tentang cara melakukannya, lihat Menggunakan antarmuka native_activity.h.

Alur

Alur umum untuk mengembangkan aplikasi native Android adalah seperti berikut:

  1. Desainlah aplikasi Anda, tentukan bagian mana saja yang akan diimplementasikan di Java, dan bagian mana yang akan diimplementasikan sebagai kode native.

    Catatan: Meskipun Anda dapat tidak menggunakan Java sama sekali, Anda mungkin akan merasakan kegunaan framework Java di Android untuk melakukan berbagai tugas, termasuk mengontrol tampilan dan UI.

  2. Buat Project aplikasi Android seperti yang Anda lakukan untuk project Android lainnya.
  3. Jika Anda menulis aplikasi khusus native, deklarasikan class NativeActivity di AndroidManifest.xml. Untuk informasi selengkapnya, lihat Aktivitas dan aplikasi native.
  4. Buat file Android.mk yang mendeskripsikan library native, termasuk nama, flag, library tertaut, dan file sumber yang akan dikompilasi dalam direktori "JNI".
  5. Jika ingin, Anda 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
    • Toolchain: Clang
    • Mode: Release
    • STL: system
  6. Tempatkan sumber native Anda dalam direktori jni project.
  7. Gunakan ndk-build untuk mengompilasi library native (.so, .a).
  8. Buat komponen Java, yang akan menghasilkan file executable .dex.
  9. Paketkan semuanya ke dalam file APK yang 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. Namun, dalam kasus tertentu–seperti untuk sensor, peristiwa input, dan aset–NDK menyediakan antarmuka native yang dapat digunakan sehingga tidak perlu memanggil melalui JNI. Untuk informasi selengkapnya tentang dukungan tersebut, lihat API native.

Baik Anda sedang mengembangkan aktivitas native atau tidak, sebaiknya buat project dengan alat build Android tradisional. Ini akan memastikan pembuatan dan pengemasan 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 memuat 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 helper statis yang di-build selain 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 tersendiri 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 mengenai cara menggunakan library statis ini, periksa aplikasi contoh aktivitas native ini 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:

  1. Buat direktori jni/ dalam direktori utama project Anda. Direktori ini menyimpan semua kode native Anda.
  2. Deklarasikan aktivitas native Anda dalam file AndroidManifest.xml.
  3. Karena aplikasi Anda tidak memiliki kode Java, tetapkan android:hasCode ke false.

    <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">
    

    Catatan: Anda dapat membuat subclass NativeActivity. Jika itu yang Anda lakukan, gunakan nama subclass tersebut, bukan NativeActivity.

    Atribut android:value tag meta-data menetapkan nama library bersama yang berisi titik entri ke aplikasi (seperti main C/C++), dengan menghilangkan awalan lib dan akhiran .so dari nama library.

              <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>
    
  4. Buat file untuk aktivitas native, lalu implementasikan fungsi yang disebut 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 memuat pointer fungsi ke berbagai implementasi callback yang perlu Anda tulis. Tetapkan pointer fungsi callback yang berlaku di ANativeActivity->callbacks ke implementasi callback Anda.
  5. Tetapkan kolom ANativeActivity->instance ke alamat instance data tertentu yang ingin Anda gunakan.
  6. Implementasikan semua hal lainnya yang ingin dilakukan aplikasi saat memulai.
  7. Implementasikan callback lain yang ditetapkan dalam ANativeActivity->callbacks. Untuk mengetahui informasi selengkapnya tentang kapan callback dipanggil, lihat Mengelola Siklus Proses Aktivitas.
  8. Kembangkan bagian aplikasi lainnya.
  9. Buat Android.mk file dalam direktori jni/ project untuk mendeskripsikan modul native ke sistem build. Untuk informasi selengkapnya, lihat Android.mk.
  10. Setelah memiliki file Android.mk, kompilasikan kode native menggunakan perintah ndk-build.
  11. $ cd <path>/<to>/<project>
    $ <ndk>/ndk-build
    
  12. 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.