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

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

  2. Buat Project aplikasi Android seperti yang Anda lakukan untuk project Android lainnya.

  3. Jika Anda menulis aplikasi khusus native, deklarasikan class NativeActivity dalam 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. 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
  6. Tempatkan sumber native Anda dalam direktori jni project.

  7. Gunakan ndk-build untuk mengompilasi library native (.so, .a).

  8. Build komponen Java, yang akan menghasilkan file executable .dex.

  9. 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:

  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.

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

    Atribut android:value tag meta-data menentukan nama library bersama yang berisi titik entri ke aplikasi (seperti main C/C++), dengan menghilangkan awalan lib 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>
    
  3. 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 di ANativeActivity->callbacks ke implementasi callback Anda.

  4. Tetapkan kolom ANativeActivity->instance ke alamat instance data tertentu yang ingin Anda gunakan.

  5. Implementasikan semua hal lainnya yang Anda ingin aktivitas lakukan saat memulai.

  6. Implementasikan callback lain yang ditetapkan di ANativeActivity->callbacks. Untuk mengetahui informasi selengkapnya tentang kapan callback dipanggil, lihat Mengelola Siklus Proses Aktivitas.

  7. Kembangkan bagian lain aplikasi.

  8. Buat Android.mk file dalam direktori jni/ project untuk mendeskripsikan modul native ke sistem build. Untuk informasi selengkapnya, lihat Android.mk.

  9. Setelah Anda memiliki file Android.mk, kompilasikan kode native menggunakan perintah ndk-build.

    cd <path>/<to>/<project>
    $NDK/ndk-build
    
  10. 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.