What is Android NDK ● A toolset that lets you embed in you app native source code ● C, C++(recently supported December 2010) and assembly(?) ● It is supported on android cupcake(1.5)+ ● It is aimed to – Bring native libraries in android (code reusability) – Make some parts of the application really fast using code generated for arm-like cpus ● Most of the time android SDK is prerequisite for NDK ● Under heavy development When should be used? ● Not just because we like c++ more than java! ● Only when its benefits outrages its drawbacks ● Why? ● – Always increases application complexity – Very difficult debugging But – OpenGL graphics to work on android in favor of NDK – Increases speed – Enable us to port most of the libraries How... ? ● Android provides 2 ways: – Writing the application using the standard SDK framework and then using JNI to access the API provided by NDK. – Write a native activity using NativeActivity class and native code to implement activity lifecycle callbacks. – Available only on Android 2.3+ – Services, Content providers must be implemented using NDK. So what exactly is JNI? ● Tip: Java Native Interface – ● Available years before android appeared Used when something java couldn't do – e.g. platform specific features – Many library java classes use JNI ● Can be used to inteface with C, C++ and assembly ● But also through that C and C++ can call native JAVA functions! ● NativeConnection class JNI example public class NativeConnection{ public native String stringFromJNI(); // This method loads as soon as the instance of the class is created static { System.loadLibrary("helloFromJNI"); } } ● HelloFromJNI.cpp JNIEXPORT jstring JNICALL Java_ceid_1ds2_cbox_helloandroid_NativeConnection_stringFromJNI( JNIEnv* env, //environment pointer jobject thiz ) //object pointer { return env->NewStringUTF("Hello from native C++ code using NJI :-D"); Native Method Names ● A native method name is concatenated from the following components: – the prefix Java_ – a mangled fully-qualified class name – an underscore (“_”) separator – a mangled method name – for overloaded native methods, two underscores (“__”) followed by the mangled argument signature Native Method Names ● Other characters: – _0XXXX: a Unicode character XXXX. – _1: the character “_” – _2: the character “;” in signatures – _3: the character “[“ in signatures ● Pretty difficult to remember! ● But there is a tool that can help us! ● javah ! javah ● ● ● Header and Stub File Generator javah [ options ] fully-qualified-classname e.g. javah -nji com.helloandroid.NativeConnection -o helloFromJNI.h ● Generates all the function prototypes in an automated way! ● Suports C-like C++ JNI strategy ● Create the native methods in java class ● Load the library in java class ● Create the function prototypes using javah in a .h file ● Create the final native source file! ● Use your native methods inside Android activity ● NativeConnection class JNI example! public class NativeConnection{ public native String stringFromJNI(); // This method loads as soon as the instance of the class is created static { System.loadLibrary("helloFromJNI"); } } ● HelloFromJNI.cpp JNIEXPORT jstring JNICALL Java_ceid_1ds2_cbox_helloandroid_NativeConnection_stringFromJNI( JNIEnv* env, //environment pointer jobject thiz ) //object pointer { return env->NewStringUTF("Hello from native C++ code using NJI :-D"); JNI in android ● ● The Android NDK is nothing more than a complement to the Android SDK that helps you to: – Generate JNI-compatible shared libraries that can run on the Android platform running on ARM CPUs. – Copy the generated libraries to a proper location of your application to be included in .apks – - A set of cross-toolchains (compilers, linkers, etc..) that can generate native ARM binaries on Linux, OS X and Windows (with Cygwin) All the rest is just JNI! Android NDK strategy ● Implement the usual application lifecycle callbacks ● Implement the native methods in a java class ● Load the library in a java class ● Create the function prototypes using javah in a .h file(optional) ● Create the final native source file ● Use your native methods somewhere inside Android activity ● Execute the commands from your working directory: ● – <pathToSDK>/tools/android update project -p . -s – <pathToNDK>/ndk-build Build the project using eclipse JNI revisited A native cannot return anything to java ● It has to be one of the JNI defined types: jboolean, jint, jfloat, jdouble, jstring . . . . j<javaType> ● To interfere with this types there also many many JNI functions ● To get the native string from javaString: ● const char *nativeString = env->GetStringUTFChars(javaString, 0); ● Some time are the same e.g. int data type is 8 bit signed same as jint. ● JNI revisited ● ● ● For example Java arrays are not guaranteed to have a continuous memory layout like C arrays. void Get<PrimitiveType>ArrayRegion(JNIEnv *env, ArrayType array, jsize start, jsize len, NativeType *buf); returns a native type array in a continues region JNIEXPORT jint JNICALL Java_IntArray_sumArray(JNIEnv *env, jobject obj, jintArray arr) { jint buf[10]; jint i, sum = 0; env->GetIntArrayRegion(arr, 0, 10, buf); for (i = 0; i < 10; i++) { sum += buf[i]; } return sum; }