Channels ▼
RSS

JVM Languages

Android on x86: Java Native Interface and the Android Native Development Kit


Java Object Usage

The String object passed over by Java program is the corresponding jstring type in the local method. The jstring type and char * in C are different. So if you just use it as a char *, an error will occur. Therefore, jstring will need to be converted into a char * in C/C++ prior to use. Here we use the JNIEnv method for conversion.

For the Object object, use the following code to get the object handler the class:

jclass objectClass = (env)->FindClass("com/ostrichmyself/jni/Structure"); 

Then use the following code to take required domain handler of the class:

jfieldID str = (env)->GetFieldID(objectClass,"nameString","Ljava/lang/String;");
jfieldID ival = (env)->GetFieldID(objectClass,"number","I");

Then use the following similar code to assign value to the incoming fields of the jobject object:

(env)->SetObjectField(theObject,str,(env)->NewStringUTF("my name is D:")); 
(env)->SetShortField(theObject,ival,10);

If there is no incoming object, then C code can use the following code to generate the new object:

jobject myNewObject = env->AllocObject(objectClass);

Java Array Processing.

For an array type, JNI provides some operable functions. For example, GetObjectArrayElement can take the incoming array and use NewObjectArray to create an array structure.

The principle of resource release is as follows:

  • Objects of C/C++ new or objects of malloc need to use the C/C++ code to release memory.
  • If the new object of the JNIEnv method is not used by Java, it must be released.
  • To convert a string object from Java to get UTF by GetStringUTFChars, you need to open up the memory, and you must release the memory after you are finished using char *. The appropriate method is ReleaseStringUTFChars.

These are brief descriptions of the basic ideas of type mapping when Java exchanges data with C/C++. For more information on Java and C/C++ data types, please refer to related Java and JNI documentation.

NDK Introduction

At this point in the discussion, we know that the Java code can visit local functions (such as C/C++) using JNI. To achieve this, you will need development tools. As we said earlier, there are a whole set of development tools based on the core Android SDK that we can use to cross-compile Java applications to applications that can run on the target Android device. Similarly, you need cross-development tools to compile the C/C++ code into applications that can run on an Android device. This tool is the Android Native Development Kit (NDK).

Prior to the NDK, third-party applications on the Android platform were developed on a special Java-based Dalvik virtual machine. The introduction of the native SDK allows developers to directly access the Android system resources and use traditional C or C++ programming languages to create applications. The application package file (.apk) can be directly embedded into the local library. In short, with the NDK, Android applications originally run on a Dalvik virtual machine can now use native code languages like C/C++ for program execution. This will bring the following benefits:

  • Performance improvement through using native code to develop any part of the program that requires high performance, and also by directly accessing the CPU and hardware.
  • The ability to reuse existing native code.

Of course, compared to the Dalvik virtual machine, using native SDK programming also has some disadvantages, such as added program complexity, difficulty in guaranteeing compatibility, the inability to access the Framework API, more difficult debugging, decreased flexibility, and so on. In addition, access to JNI itself incurs some additional performance overhead.

In short, NDK application development has pros and cons. You need to use the NDK at your own discretion. The best strategy we have found is to use the NDK to develop those parts of the application for which native code will improve performance.

The NDK includes the following major components:

  • Tools and a Build File needed to generate the native code libraries from C/C++. This includes a series of NDK commands, including the one described above: javah (use the .class files to generate the corresponding .h files), gcc, and other commands. It also includes ndk-build executable scripts.
  • A consistent local library will be embedded in the application package (application package files, that is, Apk files), which can be deployed in Android devices.
  • Support for some native system header files and libraries for all future Android platforms.

The NDK process framework for application development is shown in Figure 2. An Android application consists of three parts: Android application files, Java native library files, and dynamic libraries. These three parts are generated from different sources through the respective generation paths. For an ordinary Android application, the Android SDK generates Android applications files and Java native library files. The Android NDK generates the dynamic library files (the file with the .so extension) using non-native code (typically C source code files). Finally the Android application files, Java library files, and native dynamic libraries are installed on the target machine, and complete collaborative applications run.

Android on x86: Java Native Interface and the Android NDK
Figure 2: Flowchart of Android NDK development.

Projects developed with the NDK (referred to as NDK application projects) have components as shown in Figure 3. In contrast to typical applications developed using the Android SDK, projects developed in the NDK add the Dalvik class code, manifest files, common resources, and also the JNI and a shared library generated by the NDK.

Android on x86: Java Native Interface and the Android NDK
Figure 3: Application components for an Android NDK application.

Android adds the NDK support in its key API version. Each version includes some new NDK features, simple C/C++, a compatible STL, hardware expansion, and so on. These features make Android more open and more powerful. The mapping of the Android API and its corresponding relationship with the NDK are shown in Table 2.

API VERSION

SUPPORTED NDK VERSION

API Level 3

Android 1.5 NDK 1

API Level 4

Android 1.6 NDK 2

API Level 7

Android 2.1 NDK 3

API Level 8

Android 2.2 NDK 4

API Level 9

Android 2.3 NDK 5

API Level 12

Android 3.1 NDK 6

API Level 14

Android 4.0.1 NDK 7

API Level 15

Android 4.0.3 NDK 8

API Level 16

Android 4.1 NDK 8b

API Level 16

Android 4.2 NDK 8d

API Level 18

Android 4.3 NDK 9b

Table 1: Relationship between main Android API and NDK version.

Tip: The Meaning of Application Binary Interface (ABI)

Each piece of native code generated using the Android NDK is given a matching Application Binary Interface (ABI); the ABI precisely defines how the application and its code interact with the system at runtime. The ABI can be roughly understood as similar to an instruction set architecture (ISA) in computer architecture.

A typical ABI usually contains the following information:

  • Machine code the CPU instruction set should use
  • A runtime memory access ranking
  • The format of executable binary files (dynamic libraries, programs, and so on), as well as what type of content is allowed and supported
  • Different conventions used in passing data between the application code and systems (for example, when the function call registers and/or how to use the stack, alignment restrictions, and so on)
  • Alignment and size limits of enumerated types, structure fields, and arrays
  • The available list of function symbols for application machine code at runtime usually comes from a very specific set of libraries; each supported ABI is identified by a unique name

Android currently supports the following ABI types:

  • armeabi: This is the ABI name for the ARM CPU, which supports at least the ARMv5TE instruction set.
  • armeabi-v7a: This is another ABI name for ARM-based CPUs; it extends the armeabi CPU instruction set extensions, such as Thumb-2 instruction set extensions, floating-point processing unit directives for vector floating-point hardware.
  • x86: This is ABI name generally known for the support of x86 or IA-32 instruction set of the CPU. More specifically, its target is often referred to in the following sessions as i686 or Pentium Pro instruction set. Intel Atom processors belong to this ABI type.

These types have different compatibility. X86 is incompatible with armeabi and armeabi-v7a. The armeabi-v7a machine is compatible with armeabi, which means the armeabi framework instruction set can run on an armeabi-v7a machine, but not necessarily the other way around because some ARMv5 and ARMv6 machines do not support armeabi-v7a code. Therefore, when you build the application, users should be chosen carefully according to their corresponding ABI machine type.

Conclusion

This article introduced the Java Native Interface and the Android Native Development Kit, both of which can be used in creating Android applications for the Intel platform. The Java Native Interface allows for the use of legacy code (for example, C/C++, Delphi, and other development tools) and gives Java the ability to directly interact with the hardware for better performance. JNI also completes the mapping between Java and C/C++ to resolve the highly disparate function prototype definitions and variable types between the two languages. The Android Native Development Kit enhances performance by using native code to develop part of the program that requires high performance and by directly accessing the CPU and hardware. It also allows for the reuse of existing native code. Using the NDK does incur disadvantages, such as added program complexity, difficulty in guaranteeing compatibility, the inability to access the Framework API, more difficult debugging, and decreased flexibility. Thus, it should only be used when native code will benefit the application. The book from which this article was sampled also supplies additional information on these tools and Android development.

This article is based on material found in the book Android on x86: an Introduction to Optimizing for Intel Architecture by Iggy Krajci and Darren Cummings. Visit Intel's Industry Education website to learn more about this book: https://noggin.intel.com/intelpress/categories/books/android-on-x86. Visit the publisher's page to learn about purchasing a copy of this book: http://www.apress.com/9781430261308. Also see our Recommended Reading List for similar topics: http://noggin.intel.com/recommended-reading


Iggy Krajci is a software engineer at Go Daddy where he works on Java development. Previously, Krajci worked with SAIFE Inc. on the Android platform and its incorporation in the x86 ecosystem. Darren Cummings is the CEO and founder of Cummings Engineering and SAIFE® Inc. Before founding SAIFE Inc., Cummings served in senior systems and software engineering roles with ViaSat, General Dynamics, and the Motorola Government Group.


Portions of this article are adapted from Android on x86: an Introduction to Optimizing for Intel Architecture, published by Apress Open, an imprint of Springer, Copyright 2013 Apress. Used with permission.


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 

Video