Edit
NativeActivityとは?

NativeActivityとは、Javaのコードを一切記述することなく、Activity(Androidのアプリの単位)を作成することができるため、VMを利用せずNative(C,C++を利用した、ハードに依存した実行形式)のアプリとして実行できるため、高速な処理が可能である。Android OSのバージョンは2.2以上、API Levelは 8 からとなる。

Edit
プロジェクトの設定

Edit
AndroidManufest.xmlの設定方法

Javaのソースがないことを、AndroidManufest.xmlを通じてその設定を行う必要があり、大きくわけて2つの設定が必要である。

Edit
JavaVMを利用しない旨を宣言

AndroidManufest.xmlの中の、applivationタグに、以下の宣言を追加する。

android:hasCode="false"
例:<application android:icon="@drawable/icon" android:label="@string/app_name" android:hasCode="false">

Edit
Activityの名前

NativeActivityでは、Activityの名前を以下に設定する必要がある。

<activity android:name="android.app.NativeActivity" />

ここは、非常に違和感があると思うが、ようするにNativeActivityのフレームワークを利用している為であり、結果、1アプリに1NativeActivityだけになると考えた方が良さそうだ。

Edit
NativeActivityのファイル名を指定

この例では、MainActivity.so というコンパイルされた実行形式のファイルを指定。また、このmeta-data節は、Activity節の内側に記述すること。

<meta-data android:name="android.app.lib_name" android:value="MainActivity" />

Edit
エントリポイント名の指定

以下の例では、通常 android_main という関数から起動するものを、android_sub をいう名前でActivityを起動させたい場合の記述例。

<meta-data android:name="android.app.func_name" android:value="android_sub" />

Edit
プロジェクトの設定

プロジェクトのプロパティの中のAndroidタグにおいて、選択するライブラリを Android OS 2.3.1 以上を選択する。

Edit
Android.mkファイルの注意点

このNativeActivityをコンパイルするために、特殊なライブラリを組み込む必要があるが、このライブラリを利用するためのAndroid.mkでの指定方法には、記述の順番が非常に大きい意味を持つ。順番が違うとコンパイルできないので注意されたい。

LOCAL_PATH      := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE    := MainActivity
LOCAL_SRC_FILES := main.c
LOCAL_LDLIBS    := -llog -landroid -lEGL -lGLESv1_CM
LOCAL_STATIC_LIBRARIES := android_native_app_glue 
include $(BUILD_SHARED_LIBRARY)
$(call import-module,android/native_app_glue) 

特に最後の行は、この位置が絶対位置になる。また、下から2行目のBUILD_SHARED_LIBRARYもこの位置が固定と考えた方が良い。

Edit
新ライブラリ「native_app_glue」について

このAndroid.mkで指定した、native_app_glueは、NativeActivity用に作られたフレームワークであり、NativeActivityを実装するにあたり必要となる。(使わなくても実装できる可能性はあるが、使わない意味が無いためここでは、必須とする)特に以下の特徴を持ったライブラリとなる。

  1. onTouchなど、JavaのActivityで利用出来たイベントのCallback関数を登録することで、各イベントを取得できる。
  2. Java上のライブラリで実装されている、UIスレッドの代わりに、NativeActivity用のスレッドが作成され、android_mainがスレッドから呼び出される。

ようするに、Java上のUIライブラリに必要な最低限を提供している、ライブラリということになる。

Edit
関数リファレンス

日本語どころか、Android.orgにも説明が無いようなので、一部関数の説明をする。間違っている可能性も高いので、閲覧している諸氏にはご配慮頂きたい。

Edit
LOOPER関数

イベントプールに登録された、イベントを取得する関数

Edit
ALooper_pollOnceと、ALooper_pollAll

pollOnceは字の通り1度だけイベントを取得する。pollAllはすべてだが、この関数の場合はすべてのイベントが終わるまでコールバックされない。

int ALooper_pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData);
int ALooper_pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData);
引数番号役割
1int正の数の場合はタイムアウトさせる時間をミリ秒で指定、0の場合はblockせずに直ぐに戻る。-1の場合は、イベントが来るまで無限に待ち続ける
2int*File Discripter番号が代入される(通常はNULLで良い)
3int*イベント番号が代入される
4void**イベントのデータポインタが代入される

戻り値の詳細

戻り値説明
0, 正の数正常終了の場合
ALOOPER_POLL_WAKE = -1The poll was awoken using wake() before the timeout expired and no callbacks were executed and no other file descriptors were ready
ALOOPER_POLL_CALLBACK = -2コールバックが1つ以上実行された場合
ALOOPER_POLL_TIMEOUT = -3タイムアウトになった場合
ALOOPER_POLL_ERROR = -4その他のエラーが発生した場合

Edit
ALooper_acquireとALooper_releaseとALooper_wake

void ALooper_acquire(ALooper* looper);
void ALooper_release(ALooper* looper);
void ALooper_wake(ALooper* looper);

Edit
ALooper_addFdとALooper_removeFd

int ALooper_addFd(ALooper* looper, int fd, int ident, int events,
       ALooper_callbackFunc callback, void* data);
int ALooper_removeFd(ALooper* looper, int fd);