Advance Android Application Development

4,729 views

Published on

Advance Android training featuring NDK and Testing.

2 Comments
9 Likes
Statistics
Notes
No Downloads
Views
Total views
4,729
On SlideShare
0
From Embeds
0
Number of Embeds
15
Actions
Shares
0
Downloads
73
Comments
2
Likes
9
Embeds 0
No embeds

No notes for slide

Advance Android Application Development

  1. 1. ADVANCE ANDROID APPLICATION DEVELOPMENT<br />Ramesh Prasad<br />
  2. 2. INTRODUCTION TO NATIVE DEVELOPMENT<br />
  3. 3. Native Development<br />Android applications run in the Dalvik virtual machine. <br />The Native Development allows you to implement parts of your applications using native-code languages such as C and C++. <br />This can provide benefits to certain classes of applications, in the form of reuse of existing code and in some cases increased speed.<br />
  4. 4. When to Develop in Native Code<br />The Native Development will not benefit most applications. <br />As a developer, you need to balance its benefits against its drawbacks; notably, using native code does not result in an automatic performance increase, but always increases application complexity. <br />In general, you should only use native code if it is essential to your application, not just because you prefer to program in C/C++.<br />
  5. 5. When to Develop in Native Code<br />Typical good candidates for the NDK are self-contained, CPU-intensive operations that don't allocate much memory, such as signal processing, physics simulation, and so on. <br />Simply re-coding a method to run in C usually does not result in a large performance increase. <br />When examining whether or not you should develop in native code, think about your requirements and see if the Android framework APIs provide the functionality that you need. <br />The NDK can, however, can be an effective way to reuse a large corpus of existing C/C++ code.<br />
  6. 6. When to Develop in Native Code<br />Write your application using the Android framework and use JNI to access the APIs provided by the Android NDK. <br />This technique allows you to take advantage of the convenience of the Android framework, but still allows you to write native code when necessary. <br />You can install applications that use native code through the JNI on devices that run Android 1.5 or later.<br />
  7. 7. Bionic<br />
  8. 8. Bionic<br />Google developed a custom library for the C compiler (libc) called Bionic. This was necessary for three main reasons: <br />License: they wanted to keep GPL out of user-space. Bionic code uses the BSD license. <br />Size: the library has to be loaded in each process, so it needs to be small. Bionic is about 200K, or half the size of glibc (the GNU version of libc). <br />Speed: limited CPU power means it needs to be fast. Bionic has a small size and fast code paths, including a very fast and small custom pthread implementation. <br />
  9. 9. Bionic<br />Bionic has built-in support for important Android-specific services such as system properties and logging. <br />It doesn’t support certain POSIX features, like C++ exceptions and wide chars, which were not needed on Android. <br />Thus it’s not quite compatible with the gnu libc. <br />All native code must be compiled against bionic, not glibc. <br />
  10. 10. Architecture Support<br />The library is written to support ARM CPUs, though some x86 support is also present.<br />There is no support for other CPU architectures<br />
  11. 11. C++ Support<br />So what is different about the Bionic libc versus glibc? <br />The most striking differences are in the C++ support<br />C++<br />No C++ exceptions<br />No STL<br />Pthread<br />
  12. 12. C++ exceptions<br />The Bionic libc routines do not handle C++ exceptions.<br />They neither throw exceptions themselves, nor will they pass exceptions from a called function back through to their caller. <br />So for example, if the cmp() routine passed to qsort() throws an exception the caller of qsort() will not see it.<br />Support for C++ exceptions adds significant overhead to function calls, even just to pass thrown exceptions back to the caller. <br />As Android's primary programming language is Java, which handles exceptions entirely within the runtime package, the designers chose to omit the lower level exception support.<br />
  13. 13. STL<br />There is no C++ Standard Template Library included. <br />Developers are free supply their own, such as the free SGI implementation.<br />
  14. 14. Pthread<br />The pthread implementation appears to be completely new and developed by Google specifically for Android. <br />It is, quite deliberately, not a complete implementation of POSIX pthreads. <br />It implements those features necessary to support threads in the Dalvik JVM, and only selectively thereafter.<br />
  15. 15. Pthread<br />Mutexes, rwlocks, condvars, etc are all implemented using kernel futexes, which makes the user space implementation impressively simple.<br />There is no pthread_cancel(). Threads can exit, but can not be killed by another thread.<br />There is no pthread_atfork(). This routine is useful if you're going to fork from a threaded process, allowing cleanups of resources which should not be held in the child.<br />Thread local storage is implemented, with up to 64 keys handled. Android reserves several of these for its own use: the per-thread id and errno, as well as two variables related to OpenGL<br />POSIX realtime thread extensions like pthread_attr_{set,get}inheritsched and pthread_attr_{set,get}scope are not implemented.<br />
  16. 16. DEVELOPING WITH NDK<br />
  17. 17. NDK<br />The Android NDK is a toolset that lets you embed components that make use of native code in your Android applications.<br />The NDK provides:<br />A set of tools and build files used to generate native code libraries from C and C++ sources<br />A way to embed the corresponding native libraries into an application package file (.apk) that can be deployed on Android devices<br />A set of native system headers and libraries that will be supported in all future versions of the Android platform, starting from Android 1.5. <br />Documentation, samples, and tutorials<br />
  18. 18. NDK<br />The latest release of the NDK supports these ARM instruction sets:<br />ARMv5TE (including Thumb-1 instructions)<br />ARMv7-A (including Thumb-2 and VFPv3-D16 instructions, with optional support for NEON/VFPv3-D32 instructions)<br />x86 instructions<br />
  19. 19. Libraries<br />It provides a set of system headers for stable native APIs that are guaranteed to be supported in all later releases of the platform:<br />libc (C library) headers<br />libm (math library) headers<br />JNI interface headers<br />libz (Zlib compression) headers<br />liblog (Android logging) header<br />OpenGL ES 1.1 and OpenGL ES 2.0 (3D graphics libraries) headers<br />libjnigraphics (Pixel buffer access) header (for Android 2.2 and above).<br />A Minimal set of headers for C++ support<br />OpenSL ES native audio libraries<br />Android native application APIS<br />
  20. 20. Build System<br />The NDK also provides a build system that lets you work efficiently with your sources, without having to handle the toolchain/platform/CPU/ABI details. <br />You create very short build files to describe which sources to compile and which Android application will use them — the build system compiles the sources and places the shared libraries directly in your application project.<br />
  21. 21. Developing<br />Installation<br />Introduction<br />Managing projects<br />Building & Running<br />Debugging<br />
  22. 22. Lab<br />Hello World Tutorial<br />android-ndk-r4sampleshello-jni<br />
  23. 23. NATIVE APPLICATION DEVELOPMENT<br />
  24. 24. Application Structure <br />Java Code<br />Java Native Interface<br />Native Code<br />(Shared Object)<br />Native Code<br />(Static Library)<br />
  25. 25. Java Code<br />Your application's source code will declare one or more methods with the 'native' keyword to indicate that they are implemented through native code. E.g.:<br /> native String stringFromJNI();<br /> You must provide a native shared library that contains the implementation of these methods, which will be packaged into your application's .apk. This library must be named according to standard Unix conventions as lib<something>.so, and shall contain a standard JNI entry point (more on this later). For example:<br />libhello-jni.so<br /> Your application must explicitely load the library. For example, to load it at application startup, simply add the following to its source code:<br /> static {<br />System.loadLibrary("hello-jni");<br /> }<br /> Note that you should not use the 'lib' prefix and '.so' suffix here.<br />
  26. 26. C/C++ Code<br />Must implement a JNI Interface<br />#include <jni.h><br />jstring<br />Java_com_example_hellojni_HelloJni_stringFromJNI( <br />JNIEnv* env, jobjectthiz )<br />{<br /> return (*env)->NewStringUTF(env, "Hello from JNI !");<br />}<br />JNIEnv *: A pointer to the JNI environment. This pointer is a handle to the current thread in the Java virtual machine, and contains mapping and other hosuekeeping information. <br />jobject: A reference to the method that called this native code. If the calling method is static, this parameter would be type jclass instead of jobject. <br />jstring: The value returned by the native method.<br />Package & Java Filename<br />Function name<br />
  27. 27. Passing Strings<br />The String object in the Java language, which is represented as jstring in Java Native Interface (JNI), is a 16 bit unicode string. <br />In C a string is by default constructed from 8 bit characters. So, to access a Java language String object passed to a C or C++ function or return a C or C++ string to a Java language method, you need to use JNI conversion functions in your native method implementation. <br />The following C JNI function converts an array of C characters to a jstring:<br />(*env)->NewStringUTF(env, lastfile) <br />Iscopy – returns the result JNI_TRUE if it made a local copy of the jstring or JNI_FALSE otherwise<br />
  28. 28. Passing Strings<br />To let the Java virtual machine know you are finished with the UTF representation, call the ReleaseStringUTFChars conversion function as shown below. <br />The second argument is the original jstring value used to construct the UTF representation, and the third argument is the reference to the local representation of that String. <br /> (*env)-ReleaseStringUTFChars(env, name, mfile); <br />
  29. 29. Passing Values/Arrays<br />
  30. 30. Makefile<br />An Android.mk file is written to describe your sources to the build system. More specifically:<br />The file is really a tiny GNU Makefile fragment that will be parsed one or more times by the build system.<br />The file syntax is designed to allow you to group your sources into 'modules'. A module is one of the following:<br /> a static library<br /> a shared library<br /> Only shared libraries will be installed/copied to your application package. Static libraries can be used to generate shared libraries though. You can define one or more modules in each Android.mk file, and you can use the same source file in several modules.<br />The build system handles many details for you. For example, you don't need to list header files or explicit dependencies between generated files in your Android.mk. The NDK build system will compute these automatically for you.<br />
  31. 31. Makefile<br />
  32. 32. Makefile<br />LOCAL_PATH := $(call my-dir)<br />An Android.mk file must begin with the definition of the LOCAL_PATH variable. It is used to locate source files in the development tree. In this example, the macro function 'my-dir', provided by the build system, is used to return the path of the current directory (i.e. the directory containing the Android.mk file itself).<br /> include $(CLEAR_VARS)<br />The CLEAR_VARS variable is provided by the build system and points to a special GNU Makefile that will clear many LOCAL_XXX variables for you (e.g. LOCAL_MODULE, LOCAL_SRC_FILES, LOCAL_STATIC_LIBRARIES, etc...), with the exception of LOCAL_PATH. <br />LOCAL_MODULE := hello-jni<br />The LOCAL_MODULE variable must be defined to identify each module you describe in your Android.mk. The name must be *unique* and not contain any spaces. Note that the build system will automatically add proper prefix and suffix to the corresponding generated file. In other words, a shared library module named 'foo' will generate 'libfoo.so'.<br />LOCAL_SRC_FILES := hello-jni.c<br />The LOCAL_SRC_FILES variables must contain a list of C and/or C++ source files that will be built and assembled into a module. Note that you should not list header and included files here, because the build system will compute dependencies automatically for you; just list the source files that will be passed directly to a compiler, and you should be good.<br />
  33. 33. NDK-provided function macros<br />The following are GNU Make 'function' macros, and must be evaluated by using '$(call <function>)'. <br />They return textual information.<br />my-dir<br /> Returns the path of the current Android.mk's directory, relative to the top of the NDK build system. This is useful to define LOCAL_PATH at the start of your Android.mk as with:<br /> LOCAL_PATH := $(call my-dir)<br />
  34. 34. NDK-provided function macros<br />all-subdir-makefiles<br /> Returns a list of Android.mk located in all sub-directories of the current 'my-dir' path. For example, consider the following hierarchy:<br />sources/foo/Android.mk<br />sources/foo/lib1/Android.mk<br />sources/foo/lib2/Android.mk<br />If sources/foo/Android.mk contains the single line:<br /> include $(call all-subdir-makefiles)<br />Then it will include automatically sources/foo/lib1/Android.mk and<br /> sources/foo/lib2/Android.mk<br /> This function can be used to provide deep-nested source directory hierarchies to the build system. Note that by default, the NDK will only look for files in sources/*/Android.mk<br />
  35. 35. NDK-provided function macros<br />this-makefile<br /> Returns the path of the current Makefile (i.e. where the function<br /> is called).<br />parent-makefile<br /> Returns the path of the parent Makefile in the inclusion tree,<br /> i.e. the path of the Makefile that included the current one.<br />grand-parent-makefile<br /> Guess what...<br />
  36. 36. Module-description variables<br />
  37. 37. Lab<br />Hello JNI<br />android-ndk-r4sampleshello-jni<br />
  38. 38. USING PROCESSOR FEATURES<br />
  39. 39. USING PROCESSOR FEATURES<br />This NDK provides a small library named "cpufeatures" that can be used at runtime to detect the target device's CPU family and the optional features it supports.<br />
  40. 40. Usage<br />The library is available from sources/cpufeatures. <br />It provides an Android.mk build script that can be used to build it as a static library. To use it, you must:<br />include '$(NDK_ROOT)/sources/cpufeatures/Android.mk' at the start or end of your Android.mk file.<br /> add '$(NDK_ROOT)/sources/cpufeatures' to your LOCAL_C_INCLUDES definition.<br /> add 'cpufeatures' to your LOCAL_STATIC_LIBRARIES definition when building your final shared library.<br /> your source code can then #include <cpu-features.h> to compile against it.<br />
  41. 41. Usage<br />2<br />3<br />1<br />
  42. 42. Features<br />Two functions are provided for now:<br />AndroidCpuFamilyandroid_getCpuFamily();<br />uint64_t android_getCpuFeatures();<br />AndroidCpuFamily<br />Returns the target device's CPU Family as an enum. <br />For now, the only supported family is ANDROID_CPU_FAMILY_ARM.<br />
  43. 43. Features<br />android_getCpuFeatures() Returns the set of optional features supported by the device's CPU. The result is a set of bit-flags, each corresponding to one CPU Family-specific optional feature.<br />Currently, only the following flags are defined, for the ARM CPU Family:<br />ANDROID_CPU_ARM_FEATURE_ARMv7<br />Indicates that the device's CPU supports the ARMv7-A instruction set as supported by the "armeabi-v7a" abi<br />ANDROID_CPU_ARM_FEATURE_VFPv3<br /> Indicates that the device's CPU supports the VFPv3 hardware FPU instruction set extension. Due to the definition of 'armeabi-v7a', this will always be the case if ANDROID_CPU_ARM_FEATURE_ARMv7 is returned.<br />ANDROID_CPU_ARM_FEATURE_NEON<br />Indicates that the device's CPU supports the ARM Advanced SIMD (a.k.a. NEON) vector instruction set extension. <br />
  44. 44. Lab<br />Hello Neon<br />android-ndk-r4sampleshello-neon<br />
  45. 45. TESTING/INSTRUMENTATION<br />
  46. 46. Unit Testing<br />Unit Testing Lab<br />
  47. 47. Monkey<br />The infinite monkey theorem states that a monkey hitting keys at random on a typewriter keyboard for an infinite amount of time will almost surely type a given text, such as the complete works of William Shakespeare. <br />adb shell monkey -p com.example.android.apis -v 500<br />
  48. 48. PROFILING<br />
  49. 49. PROFILING<br />Profiling Lab<br />
  50. 50. The Endramesh130@gmail.com<br />

×