アプリが起動されてまず制御が来るのが、エントリーポイントとなる android_main 関数です。 自動生成されたコードをもとに、この流れを確認します。ここでは、冒頭の初期化部分を検討しています。
ご利用に際しては、必ずプライバシーポリシー(免責事項等)をご参照ください。
また、本サイトが初めての方は、まずこのページの注意事項をご覧ください。
投稿 January 12, 2018, 更新 December 24, 2019
Windows 10 + Visual C++ 2015 で、新しく Android ネイティブアプリを作成したときに作成される、main.cpp にある、
android_main 関数を見ます。
これはいわゆる main 関数で、
android_main 関数の最初で初期化処理を行い、 メインループですべての処理を実行して、この関数が終わるとアプリも終わる、ということです。
android_main 関数の最初の部分、メインループに入る前(センサーの初期化などサンプルコードの前)は、次のようになっていました。
void android_main(struct android_app* state) { struct engine engine; memset(&engine, 0, sizeof(engine)); state->userData = &engine; state->onAppCmd = engine_handle_cmd; state->onInputEvent = engine_handle_input; engine.app = state; → 以降、センサーの初期化やメインループに続く。
まず、引数の struct android_app* state は、いつでもどこでも使う、非常に大事なデータです。
struct engine は、定義で「アプリの保存状態です。」と、コメントされています。
生成されたコードでは main.cpp の最初の部分で定義されていますが、私は別に作成したクラスからも参照したかったので、
別のヘッダに移動しました。
例えば、
ソリューション エクスプローラーで、プロジェクト名.NativeActivity に追加することもお忘れなく。
/** * アプリの保存状態です。 */ struct engine { struct android_app* app; ASensorManager* sensorManager; const ASensor* accelerometerSensor; ASensorEventQueue* sensorEventQueue; int animating; EGLDisplay display; EGLSurface surface; EGLContext context; int32_t width; int32_t height; struct saved_state state; };
アプリが停止されるときに保存し、復帰するときに再読み込みするための構造体ということですが、 現時点(1/12/2018)ではどれぐらいのサイズまでが行儀が良いのか、良く理解していません。
とりあえず、ASensor で始まるものはセンサー系の情報であり、サンプルコードでセンサーを使用しているためなので、必須ではないと思われます。
EGL で始まるものは
最初の struct android_app* app; は、アプリ情報を管理する重要なものです。
animating は、ループ管理のようです。
最後の struct saved_state state; が、保存すべきデータを持つ構造体のようです。
まだ理解が浅くてすみません。
投稿 January 12, 2018, 更新 December 24, 2019
戻って、android_main 関数のパラメータ設定部分です。
state->userData = &engine; state->onAppCmd = engine_handle_cmd; state->onInputEvent = engine_handle_input;
state は struct android_app* です。 いつでもどこでも使う、非常に大事なデータです。
userData メンバーに engine のポインタを設定しているので、 struct android_app* があれば、struct engine を参照可能となります。
続いて、onAppCmd メンバーに engine_handle_cmd 関数へのポインタを設定しています。
APP_CMD_INIT_WINDOW や、APP_CMD_TERM_WINDOW といった Android からの
システムメッセージがあると、
最後の onInputEvent メンバーには engine_handle_input 関数へのポインタを設定しています。
タッチやキーの入力があったとき、
ちなみに、engine_handle_cmd 関数は次のようになっています。 引数 cmd にセットされたシステムメッセージを分岐して処理する、という形です。
static void engine_handle_cmd(struct android_app* app, int32_t cmd) { struct engine* engine = (struct engine*)app->userData; switch (cmd) { case APP_CMD_INIT_WINDOW: // ウィンドウの初期化処理 case APP_CMD_TERM_WINDOW: // ウィンドウの終了処理
engine_handle_input 関数は、次のようです。
static int32_t engine_handle_input(struct android_app* app, AInputEvent* event) { struct engine* engine = (struct engine*)app->userData; if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION) { // タッチ処理
ですので、メッセージ処理 engine_handle_cmd 関数、入力処理 engine_handle_input 関数、 そしてメインループから呼び出されるフレーム描画関数が、最重要関数と言えるでしょう。
Visual C++ 2015 で、Android ネイティブアプリを作成するため、新規プロジェクトを作成する手順を記録しています。
おすすめ記事はありません。