Mobil Informatikai Rendszerek Android NDK Native Development Kit Sicz-Mesziár János sicz-mesziar.janos@nik.uni-obuda.hu Mezei József mezei.jozsef@nik.uni-obuda.hu 2018. április 22.
NDK Native Development Kit Egy set of tools, amely lehetővé teszi, hogy C ill. C++ kódot futtassunk az Android alkalmazásunk alatt. A platform library felhasználásával native Activity-ket hozhatunk létre, illetve hozzáférhetünk olyan fizikai erőforrásokhoz is mint például érzékelők, touch screen, stb... Két fontosabb esetben szoktak natív kódot alkalmazni: Nagy teljesítmény igényű alkalmazások, pl játékok és fizikai szimulációk Meglévő kód-könyvtárak újrafelhasználása, közös platform kódok Támogatottság: Android Studio 2.2+, Gradle JNI (Java Native Interface) kommunikáció Cmake, ndk-build Sicz-Mesziár János Mezei József 4/22/2018 2
Fejlesztő környezet Natív kódok fordításához az alábbiak szükségesek: 1. NDK letöltése: https://developer.android.com/ndk/downloads/index.html 2. CMake: egy külső build eszköz ami a Gradle-el használható 3. LLDB: natív kód hibakereséséhez A fentiek letölthetőek SDK Manager használatával: 1. Tools > Android > SDK Manager 2. SDK Tools tab 3. LLDB, CMake, és NDK kiválasztása Sicz-Mesziár János Mezei József 4/22/2018 3
NDK Fogalmak ndk-build: Automatikus forrás fájl összegyűjtés Bináris fájlok létrehozása a forráskód alapján (*.so) Bináris fájlok bemásolása a projektbe Java: native kulcsszó használata public native int add(int x, int y); Kotlin: external kulcsszó használata external fun add(x: Int, y: Int) Native shared libraries: lefordított *.so fájlok Native static libraries: tud statikus library-vel dolgozni, vagy más library *.a fájlokat linkelni Java Native Interface (JNI): Java és C++ komponensek adatot cserélnek Application Binary Interface (ABI): meghatározza, hogy a gépi kód miként kerül interakcióval a rendszerrel futás időben Manifest: ha nincs Java kód az alkalmazásunkban (tisztán C-ben írt alkalmazás), akkor itt kell NativeActivity-t deklarálni. Sicz-Mesziár János Mezei József 4/22/2018 4
NDK Build flow 1. Eldönteni alkalmazásunk mely része lesz natív kódban. (UI-t és képernyő kezelést érdemes Java/Kotlin oldalon hagyni) 2. Új Android projekt létrehozása a szokott módon 3. Ha native-only app, akkor NativeActivity deklarálása a AndroidManifest.xml fájlban. 4. Java kód fordítása (*.dex fájl létrehozása) 5. Csomag összeállítása (*.apk fájl létrehozása) Sicz-Mesziár János Mezei József 4/22/2018 5
NDK a gyakorlatban Új módszer 1. Új Android projekt létrehozása 2. Natív kódhívást tartalmazó Kotlin osztály megírása 3. C/C++ kód megírása 4. Library inicializálása a Kotlin osztályunkban 5. CMakeList.txt kibővítése Legacy módszer 1. NDK csomag letöltése, kicsomagolása 2. Új Android projekt létrehozása 3. Natív kódhívást tartalmazó Java osztály megírása 4. Hozzá tartozó C/C++ header fájl generálása a JNI könyvtárba 5. C/C++ kód megírása 6. Android.mk fájl létrehozása 7. Application.mk fájl létrehozása Natív kód fordítása > cd app\src\main\jni > c:\android-ndk-r11c\ndkbuild 8. Library inicializálás a Java osztályunkban Sicz-Mesziár János Mezei József 4/22/2018 6
Kód megírása C/C++ kód: extern "C" JNIEXPORT jint JNICALL Java_com_example_jozsefmezei_ndk_MainActivity_sumFromJNI( JNIEnv *env,jobject /* this */, jint a, jint b) { return a+b; } Library inicializálása: companion object { init { System.loadLibrary("native-lib") } } external fun multiplyfromjni(a: Int,b: Int): Int Sicz-Mesziár János Mezei József 4/22/2018 7
CMakeList Android Studio 2.2 óta Cmake megoldja a natívkód fordítását NDK r15 óta YASM support (assembly kód fordítás ) x86 és x86-64 architektúrán! Fájl felépítése: cmake_minimum_required(version 3.4.1) add_library( native-lib SHARED # Provides a relative path to your source file(s). src/main/cpp/native-lib.cpp src/main/cpp/math-lib.cpp ) find_library( log-lib log ) target_link_libraries( native-lib ${log-lib} ) Sicz-Mesziár János Mezei József 4/22/2018 8
Java C/C++ típusok Típusok, lásd itt: $NDK\platforms\android-23\arch-arm\usr\include\jni.h Sicz-Mesziár János Mezei József 4/22/2018 9
Java C/C++ típusok Referencia típusok: Sicz-Mesziár János Mezei József 4/22/2018 10
Java/Kotlin C/C++ konverziók Néhány példa konverziókra: // use jboolean jboolean iscopy; // java string (jstring) to char* const char * res = env->getstringutfchars(mystring, &iscopy); // check JNI boolean true if(iscopy == JNI_TRUE) (*env)->releasestringutfchars(mystring, res); // release // create new jstring return (*env)->newstringutf((const char* )result.c_str()); Lásd még itt: https://developer.android.com/training/articles/perf-jni.html Sicz-Mesziár János Mezei József 4/22/2018 11