Android NDK ネイティブ API

Android NDK は、新しい Android API レベルの継続的なリリースに伴って徐々に追加された一連のネイティブ ヘッダーと共有ライブラリ ファイルを提供します。 このページでは、これらのヘッダーとファイルについて説明するとともに、これらのヘッダーとファイルを特定の Android API レベルにマッピングする方法についても説明します。

概要

アプリで NDK が提供するライブラリを使用できるようにするには、次の 2 つの基本的なステップに従います。

  1. 使用するライブラリに関連付けられたヘッダーをコードに含めます。
  2. 読み込み時にネイティブ モジュールをライブラリにリンクする必要があることをビルドシステムに通知します。たとえば、/system/lib/libfoo.so にリンクするには、次の行を Android.mk ファイルに追加します。
  3. LOCAL_LDLIBS := -lfoo
    

    複数のライブラリをリストするには、スペースを区切り記号として使用します。LOCAL_LDLIBS 変数の使用に関する詳細については、Android.mk をご覧ください。

すべての API レベルで、ビルドシステムは標準の C ライブラリ、標準の C++ ライブラリ、リアルタイム拡張機能、および pthread を自動的にリンクします。LOCAL_LDLIBS 変数を定義するときに、これらを含める必要はありません。 C ライブラリと C++ ライブラリの詳細については、Android API レベル 3 をご覧ください。

多くの場合、NDK は、新しい Android リリース向けの新しいヘッダーとライブラリを提供します。これらのファイルは、$NDK/platforms/android-<level>/<abi>/usr/include の下にあります。 NDK に Android API レベル用のヘッダーとライブラリの特定の新しいグループがない場合、そのレベルを対象とするアプリでは最後にリリースされた NDK アセットを使用する必要があります。 たとえば、Android API レベル 6 および 7 用の NDK ヘッダーまたはライブラリの新しいリリースがない状態で、Android API レベル 7 を対象とするアプリを開発する場合は、android-5/ の下にあるヘッダーとライブラリを使用する必要があります。

表 1 は、NDK でサポートされる API レベルと Android リリースの対応関係を示しています。

表 1 NDK でサポートされる API レベルと対応する Android リリース。

NDK でサポートされる API レベル Android リリース
3 1.5
4 1.6
5 2.0
8 2.2
9 2.3~3.0.x
12 3.1.x
13 3.2
14 4.0~4.0.2
15 4.0.3 および 4.0.4
16 4.1 および 4.1.1
17 4.2 および 4.2.2
18 4.3
19 4.4
21 4.4W および 5.0

特定の Android API レベル用の NDK ヘッダーとライブラリの新しい各リリースは累積的であるため、アプリをビルドするときは、ほぼすべてのケースで最後にリリースされたヘッダーを使用すれば問題ありません。 たとえば、API レベル 16 を対象とするアプリに対して、Android API レベル 21 用の NDK ヘッダーを使用することができます。 ただし、このようにすると、APK の占有領域が増大します。

Android API レベルの詳細については、API レベルとはをご覧ください。

ネイティブ API の主要なアップデート

Android API レベル 3

NDK では、Android 1.5 システム イメージ以降で実行されるネイティブ コードを開発するために以下の API が提供されています。

C ライブラリ

Android 1.5 用の C ライブラリ ヘッダーは、stdlib.hstdio.h などの標準的な名前によって使用できます。 1.5 システム イメージでヘッダーが使用できないと、ビルド時にヘッダーが見つかりません。

C++ ライブラリ

極めて最小限の C++ サポート API が使用できます。C++ ライブラリのサポートに関する詳細については、C++ ライブラリのサポートをご覧ください。

Android 固有のログ サポート

<android/log.h> には、アプリがログ メッセージをネイティブ コードからカーネルに送信するときに使用できるさまざまな定義が含まれています。 これらの定義の詳細については、$NDK/platforms/android-3/arch-arm/usr/include/android/log.h にあるコメントをご覧ください。ここで、$NDK は NDK インストールのルートです。

独自のラッパー マクロを記述して、この機能にアクセスすることができます。ログを記録する場合、ネイティブ モジュールは /system/lib/liblog.so にリンクする必要があります。 このリンクを実装するには、次の行を Android.mk ファイルに含めます。

LOCAL_LDLIBS := -llog

ZLib 圧縮ライブラリ

zlib.hzconf.h をインクルードすると、Zlib 圧縮ライブラリが使用できます。 また、次の行を Android.mk ファイルに含めて、ネイティブ モジュールを /system/lib/libz.so にリンクする必要があります。

LOCAL_LDLIBS := -lz

ダイナミック リンカー ライブラリ

dlfcn.h をインクルードすると、Android ダイナミック リンカー ライブラリの dlopen()dlsym()、および dlclose() 関数にアクセスできます。 また、次の行を Android.mk ファイルに含めて、/system/lib/libdl.so にリンクする必要があります。

LOCAL_LDLIBS := -ldl

Android API レベル 4

NDK では、Android 1.6 システム イメージ以降で実行されるネイティブ コードを開発するために以下の API が提供されています。

OpenGL ES 1.x ライブラリ

標準の OpenGL ES ヘッダー gl.h および glext.h には、ネイティブ コードから OpenGL ES 1.x レンダリング呼び出しを実行するために必要な宣言が含まれています。

これらのヘッダーを使用するには、次の行を Android.mk ファイルに含めて、ネイティブ モジュールを /system/lib/libGLESv1_CM.so にリンクする必要があります。

LOCAL_LDLIBS := -lGLESv1_CM

Android では GPU なしで端末で使用できる Open GL 1.0 対応ソフトウェアが提供されるため、すべての Android ベースの端末が OpenGL ES 1.0 をサポートします。

必要な GPU を備えた Android 端末のみが OpenGL ES 1.1 を完全にサポートします。アプリは OpenGL ES バージョンの文字列および拡張子の文字列を照会して、現在の端末が必要な機能をサポートしているかどうかを判定できます。 この照会を実行する方法の詳細については、OpenGL の仕様にある glGetString() の説明を参照してください。

さらに、マニフェスト ファイルで <uses-feature> タグを使用して、アプリが必要とする OpenGL ES のバージョンを指定する必要があります。

EGL API は、API レベル 9 以降でのみ使用できます。ただし、VM を使用すると、これらの API を介して一部の操作を実行することができます。 これらの操作には、サーフェスの作成とフリップが含まれます。 GLSurfaceView を使用する方法の例については、GLSurfaceView の概要をご覧ください。

san-angeles サンプルアプリは、これらの操作を実行し、ネイティブ コードで各フレームをレンダリングする方法の例を示しています。 このサンプルは、San Angeles Observation の優れたデモ プログラムを Android に移植した小規模なプログラムです。

Android API レベル 5

NDK では、Android 2.0 システム イメージ以降で実行されるネイティブ コードを開発するために以下の API が提供されています。

OpenGL ES 2.0 ライブラリ

標準の OpenGL ES 2.0 ヘッダー <GLES2/gl2.h> および <GLES2/gl2ext.h> には、ネイティブ コードから OpenGL ES 2.0 レンダリング呼び出しを実行するために必要な宣言が含まれています。これらのレンダリング呼び出しにより、GLSL 言語を使って頂点シェーダーやフラグメント シェーダーを定義および使用する機能が提供されます。

OpenGL ES 2.0 を使用するには、次の行を Android.mk ファイルに含めて、ネイティブ モジュールを /system/lib/libGLESv2.so にリンクする必要があります。

LOCAL_LDLIBS := -lGLESv2

すべての端末が OpenGL ES 2.0 をサポートするわけではありません。アプリは OpenGL ES バージョンの文字列および拡張子の文字列を照会して、現在の端末が必要な機能をサポートしているかどうかを判定できます。 この照会を実行する方法の詳細については、OpenGL の仕様にある glGetString() の説明を参照してください。

さらに、マニフェスト ファイルで <uses-feature> タグを使用して、アプリが必要とする OpenGL ES のバージョンを指定する必要があります。 <uses-feature> の OpenGL ES の設定に関する詳細については、OpenGL ES をご覧ください。

hello-gl2 サンプルアプリは、NDK で OpenGL ES 2.0 を使用する方法の基本的な例を示しています。

EGL API は、API レベル 9 以降でのみ使用できます。ただし、VM を使用すると、これらの API を介して一部の操作を実行することができます。 これらの操作には、サーフェスの作成とフリップが含まれます。 GLSurfaceView を使用する方法の例については、GLSurfaceView の概要をご覧ください。

: Android エミュレータは OpenGL ES 2.0 ハードウェア エミュレーションをサポートしていません。 この API を使用するコードの実行とテストには、OpenGL ES 2.0 をサポートできるハードウェアを備えた実機が必要です。

Android API レベル 8

NDK では、Android 2.2 システム イメージ以降で実行されるネイティブ コードを開発するために以下の API が提供されています。

jnigraphics

jnigraphics ライブラリは、ネイティブ コードで Java ビットマップ オブジェクトのピクセル バッファに確実にアクセスできるようにする C ベースのインターフェースを公開します。 jnigraphics を使用するためのワークフローは次のとおりです。

  1. AndroidBitmap_getInfo() を使用して、任意のビットマップ ハンドルに関して、幅や高さなどの情報を JNI から取得します。
  2. AndroidBitmap_lockPixels() を使用して、ピクセル バッファをロックし、ピクセル バッファへのポインタを取得します。このようにすると、アプリが AndroidBitmap_unlockPixels() を呼び出すまで、ピクセルが移動しません。
  3. ネイティブ コードで、ピクセル形式、幅、およびその他の特性に適合するようにピクセル バッファを変更します。
  4. AndroidBitmap_unlockPixels() を呼び出して、バッファをロック解除します。

jnigraphics を使用するには、<bitmap.h> ヘッダーをソースコードに含め、次の行を Android.mk ファイルに含めて、jnigraphics にリンクする必要があります。

LOCAL_LDLIBS += -ljnigraphics

この機能に関する追加情報については、bitmap.h ファイルのコメントをご覧ください。

Android API レベル 9

NDK では、Android 2.3 システム イメージ以降で実行されるネイティブ コードを開発するために以下の API が提供されています。

EGL

EGL は、OpenGLES サーフェスを割り当てたり、管理したりするためのネイティブ プラットフォーム インターフェースを提供します。この機能の詳細については、EGL ネイティブ プラットフォーム インターフェースをご覧ください。

EGL を使用すると、ネイティブ コードから次の操作を実行できます。

  • サポートされる EGL 設定をリストする。
  • OpenGLES サーフェスの割り当てと解放を実行する。
  • サーフェスをスワップまたはフリップする。

次のヘッダーは EGL 機能を提供します。

  • EGL/egl.h: EGL API のメイン定義。
  • EGL/eglext.h:EGL の拡張機能関連の定義。

システムの EGL ライブラリにリンクするには、次の行を Android.mk ファイルに追加します。

LOCAL_LDLIBS += -lEGL

OpenSL ES

Android ネイティブ オーディオの処理は、Khronos Group の OpenSL ES 1.0.1 API に基づいています。

標準の OpenSL ES ヘッダー OpenSLES.h および OpenSLES_Platform.h には、Android のネイティブ サイドからオーディオの入出力を実行するために必要な宣言が含まれています。また、OpenSL ES の NDK 配布により、Android 固有の拡張機能が提供されます。 これらの拡張機能の詳細については、OpenSLES_Android.hOpenSLES_AndroidConfiguration.h のコメントをご覧ください。

システム ライブラリ libOpenSLES.so によって、ネイティブ オーディオのパブリック関数が実装されます。次の行を Android.mk に追加して、このライブラリにリンクします。

LOCAL_LDLIBS += -lOpenSLES

OpenSL ES API の詳細については、$NDK/docs/Additional_library_docs/opensles/index.html をご覧ください。ここで、$NDK は NDK インストール ルート ディレクトリです。

Android ネイティブ アプリ API

API レベル 9 以降では、Java を使用せずに、ネイティブ コードで Android アプリ全体を記述することができます。

注: VM でアプリを実行するには、ネイティブ コードでアプリを記述するだけでは不十分です。 さらに、アプリは JNI を介して Android プラットフォームのほとんどの機能にアクセスする必要もあります。

このリリースでは、次のネイティブ ヘッダーを提供します。

  • <native_activity.h>
  • <looper.h>
  • <input.h>
  • <keycodes.h>
  • <sensor.h>
  • <rect.h>
  • <window.h>
  • <native_window.h>
  • <native_window_jni.h>
  • <configuration.h>
  • <asset_manager.h>
  • <storage_manager.h>
  • <obb.h>

これらのヘッダーの詳細については、NDK API リファレンス ドキュメントとそれぞれのヘッダーのコメントを参照してください。 また、ネイティブ アプリの記述に関する広範なトピックの詳細については、ネイティブ アクティビティとアプリをご覧ください。

これらのヘッダーを 1 つ以上含めるときも、libandroid.so ライブラリにリンクする必要があります。 libandroid.so にリンクするには、次の行を Android.mk ファイルに含めます。

LOCAL_LDLIBS += -landroid

Android API レベル 14

NDK では、Android 4.0 システム イメージ以降で実行されるネイティブ コードを開発するために以下の API が提供されています。

OpenMAX AL

Android ネイティブ マルチメディアの処理は、Khronos Group の OpenMAX AL 1.0.1 API に基づいています。

標準の OpenMAX AL ヘッダー <OMXAL/OpenMAXAL.h> および <OMXAL/OpenMAXAL_Platform.h> には、Android のネイティブ サイドからマルチメディア出力を実行するために必要な宣言が含まれています。

また、OpenMAX AL の NDK 配布により、Android 固有の拡張機能が提供されます。これらの拡張機能の詳細については、OpenMAXAL_Android.h のコメントをご覧ください。

システム ライブラリ libOpenMAXAL.so によって、ネイティブ マルチメディアのパブリック関数が実装されます。このライブラリにリンクするには、次の行を Android.mk ファイルに含めます。

    LOCAL_LDLIBS += -lOpenMAXAL

このトピックに関する詳細については、$NDK/docs/openmaxal/index.html をご覧ください。ここで、$NDK は NDK インストールのルート ディレクトリです。

OpenSL ES

この Android API レベルの OpenSL ES サポートにより、PCM サポートが追加されます。NDK の OpenSL ES サポートに関する詳細については、OpenSL ES をご覧ください。

Android API レベル 18

NDK では、Android 4.3 システム イメージ以降で実行されるネイティブ コードを開発するために以下の API が提供されています。

OpenGL ES 3.0

標準の OpenGL ES 3.0 ヘッダー gl3.h および gl3ext.h には、ネイティブ コードから OpenGL ES 3.0 レンダリング呼び出しを実行するために必要な宣言が含まれています。 これらのレンダリング呼び出しにより、GLSL 言語を使って頂点シェーダーやフラグメント シェーダーを定義および使用する機能が提供されます。

OpenGL ES 3.0 を使用するには、次の行を Android.mk ファイルに含めて、ネイティブ モジュールを /system/lib/libGLESv3.so にリンクする必要があります。

LOCAL_LDLIBS := -lGLESv3

すべての端末が OpenGL ES 3.0 をサポートするわけではありません。アプリは OpenGL ES バージョンの文字列および拡張子の文字列を照会して、現在の端末が必要な機能をサポートしているかどうかを判定できます。 この照会を実行する方法の詳細については、OpenGL の仕様にある glGetString() の説明を参照してください。

さらに、マニフェスト ファイルで <uses-feature> タグを使用して、アプリが必要とする OpenGL ES のバージョンを指定する必要があります。 <uses-feature> の OpenGL ES の設定に関する詳細については、OpenGL ES をご覧ください。

gles3jni サンプルアプリは、NDK で OpenGL ES 3.0 を使用する方法の基本的な例を示しています。

: Android エミュレータは OpenGL ES 3.0 ハードウェア エミュレーションをサポートしていません。 この API を使用するコードの実行とテストには、OpenGL ES 3.0 をサポートできるハードウェアを備えた実機が必要です。

Android API レベル 21

NDK では、Android 4.3 システム イメージ以降で実行されるネイティブ コードを開発するために以下の API が提供されています。

OpenGL ES 3.1

標準の OpenGL ES 3.1 ヘッダー gl31.h および gl3ext.h には、ネイティブ コードから OpenGL ES 3.1 レンダリング呼び出しを実行するために必要な宣言が含まれています。 これらのレンダリング呼び出しにより、GLSL 言語を使って頂点シェーダーやフラグメント シェーダーを定義および使用する機能が提供されます。

OpenGL ES 3.1 を使用するには、次の行を Android.mk ファイルに含めて、ネイティブ モジュールを /system/lib/libGLESv3.so にリンクする必要があります。

LOCAL_LDLIBS := -lGLESv3

すべての端末が OpenGL ES 3.1 をサポートするわけではありません。アプリは OpenGL ES バージョンの文字列および拡張子の文字列を照会して、現在の端末が必要な機能をサポートしているかどうかを判定できます。 この照会を実行する方法の詳細については、OpenGL の仕様にある glGetString() の説明を参照してください。

さらに、マニフェスト ファイルで <uses-feature> タグを使用して、アプリが必要とする OpenGL ES のバージョンを指定する必要があります。 <uses-feature> の OpenGL ES の設定に関する詳細については、OpenGL ES をご覧ください。

gles3jni サンプルアプリは、NDK で OpenGL ES 3.1 を使用する方法の基本的な例を示しています。

: Android エミュレータは OpenGL ES 3.1 ハードウェア エミュレーションをサポートしていません。 この API を使用するコードの実行とテストには、OpenGL ES 3.1 をサポートできるハードウェアを備えた実機が必要です。