Bermigrasi dari NativeActivity Bagian dari Android Game Development Kit.
Halaman ini menjelaskan cara melakukan migrasi dari
NativeActivity
ke
GameActivity
dalam project game Android Anda.
GameActivity
didasarkan pada NativeActivity
dari framework
Android, dengan peningkatan dan fitur baru:
- Mendukung
Fragment
dari Jetpack. - Menambahkan dukungan
TextInput
untuk memfasilitasi integrasi keyboard virtual. - Menangani peristiwa sentuh dan tombol di class Java
GameActivity
, bukan antarmukaNativeActivity
onInputEvent
.
Sebelum bermigrasi, sebaiknya baca
panduan memulai, yang menjelaskan cara
menyiapkan dan mengintegrasikan GameActivity
dalam project Anda.
Update skrip build Java
GameActivity
didistribusikan sebagai
library Jetpack. Pastikan untuk menerapkan langkah-langkah update skrip Gradle
yang dijelaskan dalam panduan memulai:
Aktifkan library Jetpack di file
gradle.properties
project Anda:android.useAndroidX=true
Secara opsional, tentukan versi Prefab dalam file
gradle.properties
yang sama, misalnya:android.prefabVersion=2.0.0
Aktifkan fitur Prefab di file
build.gradle
aplikasi Anda:android { ... // other configurations buildFeatures.prefab true }
Tambahkan dependensi
GameActivity
ke aplikasi Anda:- Tambahkan library
core
dangames-activity
. - Jika API level minimum yang didukung saat ini kurang dari 16, update ke setidaknya 16.
- Update versi SDK yang telah dikompilasi ke versi yang
diperlukan library
games-activity
. Biasanya Jetpack memerlukan versi SDK terbaru pada waktu build rilis.
File
build.gradle
Anda yang telah diupdate mungkin terlihat seperti ini:android { compiledSdkVersion 33 ... // other configurations. defaultConfig { minSdkVersion 16 } ... // other configurations. buildFeatures.prefab true } dependencies { implementation 'androidx.core:core:1.9.0' implementation 'androidx.games:games-activity:1.2.2' }
- Tambahkan library
Update kode Kotlin atau Java
NativeActivity
dapat digunakan sebagai aktivitas pengaktifan dan membuat aplikasi
layar penuh. Saat ini, GameActivity tidak dapat digunakan sebagai aktivitas
pengaktifan. Aplikasi harus mengambil class dari GameActivity
dan menggunakannya sebagai
aktivitas pengaktifan. Anda juga harus membuat perubahan konfigurasi tambahan untuk
membuat aplikasi layar penuh.
Langkah-langkah berikut mengasumsikan bahwa aplikasi Anda menggunakan NativeActivity
sebagai aktivitas
pengaktifan. Jika tidak demikian, Anda dapat melewati sebagian besar langkah tersebut.
Buat file Kotlin atau Java untuk menghosting aktivitas pengaktifan baru. Misalnya, kode berikut membuat
MainActivity
sebagai aktivitas pengaktifan dan memuat library native utama aplikasi,libAndroidGame.so
:Kotlin
class MainActivity : GameActivity() { override fun onResume() { super.onResume() // Use the function recommended from the following page: // https://d.android.com/training/system-ui/immersive hideSystemBars() } companion object { init { System.loadLibrary("AndroidGame") } } }
Java
public class MainActivity extends GameActivity { protected void onResume() { super.onResume(); // Use the function recommended from // https://d.android.com/training/system-ui/immersive hideSystemBars(); } static { System.loadLibrary("AndroidGame"); } }
Buat tema aplikasi layar penuh di file
res\values\themes.xml
:<resources xmlns:tools="http://schemas.android.com/tools"> <!-- Base application theme. --> <style name="Application.Fullscreen" parent="Theme.AppCompat.Light.NoActionBar"> <item name="android:windowFullscreen">true</item> <item name="android:windowContentOverlay">@null</item>" </style> </resources>
Terapkan tema ke aplikasi di file
AndroidManifest.xml
:<application android:theme=”@style/Application.Fullscreen”> <!-- other configurations not listed here. --> </application>
Untuk petunjuk mendetail tentang mode layar penuh, lihat panduan imersif dan contoh implementasi di repo contoh game.
Panduan migrasi ini tidak mengubah nama library native. Jika Anda mengubahnya, pastikan nama library native konsisten di tiga lokasi berikut:
Kode Kotlin atau Java:
System.loadLibrary(“AndroidGame”)
AndroidManifest.xml
:<meta-data android:name="android.app.lib_name" android:value="AndroidGame" />
Di dalam file skrip build C/C++, misalnya
CMakeLists.txt
:add_library(AndroidGame ...)
Update skrip build C/C++
Petunjuk di bagian ini menggunakan cmake
sebagai contoh. Jika aplikasi Anda
menggunakan ndk-build
, Anda perlu memetakannya ke perintah yang setara yang dijelaskan di
halaman dokumentasi ndk-build.
Implementasi C/C++ GameActivity telah menyediakan rilis kode sumber. Untuk versi 1.2.2 yang lebih baru, rilis library statis disediakan. Library statis adalah jenis rilis yang direkomendasikan.
Rilis dikemas dalam AAR dengan utilitas
prefab
. Kode native mencakup sumber C/C++ GameActivity dan
kode native_app_glue
. Keduanya harus di-build bersama dengan
kode C/C++ aplikasi Anda.
Aplikasi NativeActivity
sudah menggunakan kode native_app_glue
yang dikirimkan di dalam NDK. Anda harus menggantinya dengan native_app_glue
versi GameActivity. Selain itu, semua langkah cmake
yang didokumentasikan dalam
panduan memulai tetap berlaku:
Impor library statis C/C++ atau kode sumber C/++ ke project Anda sebagai berikut.
Library statis
Dalam file
CMakeLists.txt
project Anda, impor library statisgame-activity
ke dalam modul prefabgame-activity_static
:find_package(game-activity REQUIRED CONFIG) target_link_libraries(${PROJECT_NAME} PUBLIC log android game-activity::game-activity_static)
Kode sumber
Dalam file
CMakeLists.txt
project Anda, impor paketgame-activity
lalu tambahkan ke target Anda. Paketgame-activity
memerlukanlibandroid.so
, jadi jika tidak ada, Anda juga harus mengimpornya.find_package(game-activity REQUIRED CONFIG) ... target_link_libraries(... android game-activity::game-activity)
Hapus semua referensi ke kode
native_app_glue
NDK, seperti:${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c ... set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -u ANativeActivity_onCreate")
Jika Anda menggunakan rilis kode sumber, sertakan file sumber
GameActivity
. Jika tidak, lewati langkah ini.get_target_property(game-activity-include game-activity::game-activity INTERFACE_INCLUDE_DIRECTORIES) add_library(${PROJECT_NAME} SHARED main.cpp ${game-activity-include}/game-activity/native_app_glue/android_native_app_glue.c ${game-activity-include}/game-activity/GameActivity.cpp ${game-activity-include}/game-text-input/gametextinput.cpp)
Mengatasi masalah UnsatisfiedLinkError
Jika Anda menemukan UnsatsifiedLinkError
untuk
fungsi com.google.androidgamesdk.GameActivity.initializeNativeCode()
, tambahkan
kode ini ke file CMakeLists.txt
:
set(CMAKE_SHARED_LINKER_FLAGS
"${CMAKE_SHARED_LINKER_FLAGS} -u \
Java_com_google_androidgamesdk_GameActivity_initializeNativeCode")
Update kode sumber C/C++
Ikuti langkah-langkah berikut untuk mengganti referensi NativeActivity
di aplikasi Anda
dengan GameActivity
:
Gunakan
native_app_glue
yang dirilis denganGameActivity
. Telusuri dan ganti semua penggunaanandroid_native_app_glue.h
dengan:#include <game-activity/native_app_glue/android_native_app_glue.h>
Tetapkan filter peristiwa gerakan dan filter peristiwa tombol ke
NULL
agar aplikasi Anda dapat menerima peristiwa input dari semua perangkat input. Anda biasanya dapat melakukannya dalam fungsiandroid_main()
:void android_main(android_app* app) { ... // other init code. android_app_set_key_event_filter(app, NULL); android_app_set_motion_event_filter(app, NULL); ... // additional init code, and game loop code. }
Hapus kode terkait
AInputEvent
, lalu ganti dengan implementasiInputBuffer
GameActivity:while (true) { // Read all pending events. int events; struct android_poll_source* source; // If not animating, block forever waiting for events. // If animating, loop until all events are read, then continue // to draw the next frame of animation. while ((ALooper_pollAll(engine.animating ? 0 : -1, nullptr, &events, (void**)&source)) >= 0) { // Process this app cycle or inset change event. if (source) { source->process(source->app, source); } ... // Other processing. // Check if app is exiting. if (state->destroyRequested) { engine_term_display(&engine); return; } } // Process input events if there are any. engine_handle_input(state); if (engine.animating) { // Draw a game frame. } } // Implement input event handling function. static int32_t engine_handle_input(struct android_app* app) { auto* engine = (struct engine*)app->userData; auto ib = android_app_swap_input_buffers(app); if (ib && ib->motionEventsCount) { for (int i = 0; i < ib->motionEventsCount; i++) { auto *event = &ib->motionEvents[i]; int32_t ptrIdx = 0; switch (event->action & AMOTION_EVENT_ACTION_MASK) { case AMOTION_EVENT_ACTION_POINTER_DOWN: case AMOTION_EVENT_ACTION_POINTER_UP: // Retrieve the index for the starting and the ending of any secondary pointers ptrIdx = (event->action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT; case AMOTION_EVENT_ACTION_DOWN: case AMOTION_EVENT_ACTION_UP: engine->state.x = GameActivityPointerAxes_getAxisValue( &event->pointers[ptrIdx], AMOTION_EVENT_AXIS_X); engine->state.y = GameActivityPointerAxes_getAxisValue( &event->pointers[ptrIdx], AMOTION_EVENT_AXIS_Y); break; case AMOTION_EVENT_ACTION_MOVE: // Process the move action: the new coordinates for all active touch pointers // are inside the event->pointers[]. Compare with our internally saved // coordinates to find out which pointers are actually moved. Note that there is // no index embedded inside event->action for AMOTION_EVENT_ACTION_MOVE (there // might be multiple pointers moved at the same time). ... break; } } android_app_clear_motion_events(ib); } // Process the KeyEvent in a similar way. ... return 0; }
Tinjau dan update logika yang dilampirkan ke
AInputEvent
NativeActivity. Seperti yang ditunjukkan pada langkah sebelumnya, pemrosesanInputBuffer
GameActivity berada di luar loopALooper_pollAll()
.Ganti penggunaan
android_app::activity->clazz
denganandroid_app:: activity->javaGameActivity
. GameActivity mengganti nama instanceGameActivity
Java.
Langkah-langkah tambahan
Langkah-langkah sebelumnya mencakup fungsi NativeActivity, tetapi GameActivity
memiliki
fitur tambahan yang dapat Anda gunakan:
- TextInput.
- Pengontrol Game.
- Fragmen.
- Perintah InSet jendela baru yang ditetapkan di NativeAppGlueAppCmd.
Sebaiknya jelajahi fitur ini dan gunakan fitur yang sesuai untuk game Anda.
Jika ada pertanyaan atau rekomendasi mengenai GameActivity atau library AGDK lainnya, buat bug untuk memberi tahu kami.