SlideShare a Scribd company logo
NDK Primer
Ron Munitz
Founder & CEO - The PSCG
Founder & CTO - Nubo
ron@nubosoftware.com
ron@android-x86.org
https://github.com/ronubo/
Wearables
DevCon
March 2014
@ronubo
PSCG
This work is licensed under the Creative Commons
Attribution-ShareAlike 4.0 International License.
To view a copy of this license, visit http://creativecommons.org/licenses/by-
sa/4.0/
© Copyright Ron Munitz 2014
PSCG
About://Ron Munitz
● Distributed Fault Tolerant Avionic Systems
○ Linux, VxWorks, very esoteric libraries, 0’s and 1’s
● Highly distributed video routers
○ Linux
● Real Time, Embedded, Server bringups
○ Linux, Android , VxWorks, Windows, devices, BSPs, DSPs,...
● Distributed Android
○ Rdroid? Cloudroid? Too busy working to get over the legal naming, so
no name is officially claimed for my open source
● What currently keeps me busy:
○ Running the PSCG, a Embedded/Android consulting and Training
○ Managing R&D at Nubo
○ Lecturing at Afeka’s college of Engineering
○ Amazing present, endless opportunities. (Wish flying took less time)
@ronubo
PSCG
Agenda
● Part I: Java
○ Java Native Interface (JNI) - Theory
○ Hello World Tutorial - Practice
● Part II: JNI in the AOSP
● Part III: Native Android Apps
Part I
The Java Native Interface
PSCG
Introduction
The JNI is a native programming interface. It allows Java
code that runs inside a Java Virtual Machine (VM) to
interoperate with applications and libraries written in other
programming languages, such as C, C++, and assembly.
All JVM implementation need to implement the JNI
specification to allow compatibility with native code
libraries.
JNI to Java ⇔ __asm to C
Motivation
● The standard Java class library does not support the
platform-dependent features needed by the application.
○ For example NEON, SSSE3, ...
● You already have a library written in another language,
and wish to make it accessible to Java code through the
JNI.
● You want to implement a small portion of time-critical
code in a lower-level language such as assembly.
Wearable Motivation
● Reduce CPU cycles (and battery drain rate!) on
intensive computations
● Add designated features for simple add-on hardware
without having to support an entire ecosystem for that
● Media processing in Android: All is being done natively
this way or another
● Porting legacy code
● Protecting your logic and algorithms from rev-eng
JNI Pitfalls
● Subtle errors in the use of JNI can destabilize the entire JVM in
ways that are very difficult to reproduce and debug.
● An application that relies on JNI loses the platform portability Java
offers (a partial workaround is to write a separate implementation of
JNI code for each platform and have Java detect the operating
system and load the correct one at runtime).
● The JNI framework does not provide any automatic garbage
collection for non-JVM memory resources allocated by code
executing on the native side. Consequently, native side code (such
as assembly language) must assume the responsibility for explicitly
releasing any such memory resources that it itself acquires.
NDK Primer (Wearable DevCon 2014)
JNI environment pointers
The JNI interface is organized like a C++ virtual function table. It
enables a VM to provide multiple versions of JNI function tables.
The JNI interface pointer is only valid in the current thread.
Native methods receive the JNI interface pointer as an argument.
The VM is guaranteed to pass the same interface pointer to a native
method when it makes multiple calls to the native method from the
same Java thread.
Loading and linking native methods
Native methods are loaded with the System.loadLibrary() method.
In the following example, the class initialization method loads a platform-
specific native library in which the native method f is defined:
class Cls {
native boolean f(int i, String s);
static {
System.loadLibrary(“pkg_Cls”);
}
}
The library pkg_Cls is platform specific. On a Unix derived system it will be
named libpkg_Cls.so and on windows system it will be named pkg_Cls.dll.
Loading and linking native methods
(cont.)
Dynamic linkers resolve entries based on their 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
The signature of function f above is, as created by javah:
JNIEXPORT jboolean JNICALL Java_Cls_f(JNIEnv *, jobject, jint, jstring);
JNIEnv * - pointer to the JNI interface
jobject - a pointer to the calling java class for a static method or a
pointer to the calling java object for non-static method.
Referencing java objects
● Primitive types, such as integers, characters, and so on, are
copied between Java and native code (call by value)
● Arbitrary Java objects, on the other hand, are passed by
reference.
● The VM must keep track of all objects that have been passed to
the native code, so that these objects are not freed by the
garbage collector.
● The native code, in turn, must have a way to inform the VM that it
no longer needs the objects.
● The JNI divides object references used by the native code into two
categories: local and global references.
○ Local references are valid for the duration of a native method
call, and are automatically freed after the native method
returns.
○ Global references remain valid until they are explicitly freed.
Referencing java objects
(Cont.)
● Objects are passed to native methods as local references. All Java
objects returned by JNI functions are local references.
● The JNI allows the programmer to create global references from
local references. JNI functions that expect Java objects accept both
global and local references. A native method may return a local or
global reference to the VM as its result.
● Since the VM needs a certain amount of space to keep track of
a local reference, creating too many local references may
cause the system to run out of memory.
● Local references are only valid in the thread in which they are
created.
● Local references are automatically garbage collected once the
function returns.
Invocation API
Used to call java from c/c++ code.
The JNI interface pointer (JNIEnv) is valid only in the
current thread. Should another thread need to access the
Java VM, it must first call AttachCurrentThread() to attach
itself to the VM and obtain a JNI interface pointer. Once
attached to the VM, a native thread works just like an
ordinary Java thread running inside a native method. The
native thread remains attached to the VM until it calls
DetachCurrentThread() to detach itself.
Accessing fields and methods
● The JNI allows native code to access the fields and to call the
methods of Java objects.
● The JNI identifies methods and fields by their symbolic names and
type signatures.
● A two-step process factors out the cost of locating the field or
method from its name and signature. For example, to call the
method f in class cls, the native code first obtains a method ID, as
follows:
jmethodID methodId =
env->GetMethodID(cls, “f”, “(ILjava/lang/String;)D”);
The native code can then use the method ID repeatedly without the
cost of method lookup, as follows:
jdouble result = env->CallDoubleMethod(obj, methodID,
10, str);
Exception handling
There are two ways to handle an exception in native code:
● The native method can choose to return
immediately, causing the exception to be thrown in
the Java code that initiated the native method call.
● The native code can clear the exception by calling
ExceptionClear(), and then execute its own
exception-handling code.
After an exception has been raised, the native code must
first clear the exception before making other JNI calls.
JNI types and data structures
Java Type Native Type Description
boolean jboolean unsigned 8 bits
byte jbyte signed 8 bits
char jchar unsigned 16 bits
short jshort signed 16 bits
int jint signed 32 bits
long jlong signed 64 bits
float jfloat 32 bits
double jdouble 64 bits
JNI types and data structures
JVM Type Signatures
Type Signature Java Type
Z boolean
B byte
C char
S short
I int
J long
F float
D double
L fully-qualified-class ; fully-qualified-class
[ type type[]
( arg-types ) ret-type method type
For example, the Java method:
long f(int n, String s, int[]
arr);
has the following type signature:
(ILjava/lang/String;[I)J
JNI types and data structures
Java Type Native Type Description
boolean jboolean unsigned 8 bits
byte jbyte signed 8 bits
char jchar unsigned 16 bits
short jshort signed 16 bits
int jint signed 32 bits
long jlong signed 64 bits
float jfloat 32 bits
double jdouble 64 bits
JNI types and data structures
Tutorial 1: DIY
HelloWorld
Linux_x86-64/Oracle JDK 7.0/JNI
Step 1: HelloWorld.java
class HelloWorld
{
private native void print();
public static void main(String[] args)
{
new HelloWorld().print();
}
static {
System.loadLibrary("HelloWorld"); // Note: No “lib”, No “.so”.
}
}
Compile: javac HelloWorld.java .
Run: java HelloWorld
Fail: java.lang.UnsatisfiedLinkError: no HelloWorld in java.library.path . Not surprising…
Step 2: Auto Generate Headers
~/edu/jni$ javah HelloWorld # Note: javah takes a class name
:~/edu/jni$ cat HelloWorld.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloWorld */
#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/* Class: HelloWorld Method: print Signature: ()V */
JNIEXPORT void JNICALL Java_HelloWorld_print (JNIEnv *, jobject); // “Java” - because I didn’t use a package.
#ifdef __cplusplus
}
#endif
#endif
Step 3: HelloWorld.c
#include <stdio.h>
#include "HelloWorld.h"
JNIEXPORT void JNICALL Java_HelloWorld_print
(JNIEnv *env, jobject obj)
{
printf("Hello World!n");
}
Compile: gcc -shared -fPIC -I<YourJvmIncludePaths> HelloWorld.c -o libHelloWorld.so
Run: In a couple of slides.
Fail: Easily. GCC flags are subtle.
Step 3.5: Build the Shared Library
Let’s have a look at the following concrete
example:
gcc -shared -fPIC 
-I/usr/lib/jvm/jdk1.7.0/include/linux -I/usr/lib/jvm/jdk1.7.0/include 
HelloWorld.c -o libHelloWorld.so
-shared: Create a shared object. (In Windows: a “DLL”)
-fPIC: Position Independent Code - Always create Shared Object with that flag.
-I<et. al>: Location of jni.h, and files included from there.
-o libHelloWorld.so: Everything between “lib” and “.so” must match the name in loadLibrary().
Step 4: Run
java -Djava.library.path=. HelloWorld
Note: It is important to tell java where to look for your shared libraries.
Otherwise you will see the same error listed in Step 1.
Hello World!
Part II
SystemServer’s native side:
libandroid_services
PSCG
The NDK in a nutshell
● Available as a JNI “SDK” to Android
application developers.
○ In the platform itself there is no need for it, just as
there is no need for the Android SDK
● Eases porting of existing Linux code to
Android
○ As long as it is not heavily depended on glibc
features, X, QT/GTK etc.
● Enables common code for multiple
architectures
○ On the nominal portable C/C++ code case
○ @see Application.mk
JNI in the Android platform
● @see
frameworks/base/services/java/com/android/server/SystemServer.java
● This is where the Java Android OS starts.
● And it is heavily relying on native functions
SystemServer.java revisited
public class SystemServer {
private static final String TAG = "SystemServer";
//...
private static native void nativeInit(); /*Called to initialize native system services.*/
public static void main(String[] args) {
// ...
// Set runtime libary property (Dalvik/ART/..) ...
// Set initial system time (to workaround some negative value bugs) ...
// Enable profiler snapshot if profiler is enabled ...
// Take care of HeapSize for the System Server which never dies ...
// ...
System.loadLibrary("android_servers");
Slog.i(TAG, "Entered the Android system server!");
nativeInit(); /* Initializes native services - This is a JNI call to
frameworks/base/services/jni/com_android_server_SystemServer.cpp …
See next slide*/
ServerThread thr = new ServerThread();
thr.initAndLoop(); // Note to self: so long init2()!!!
}
}
com_android_server_SystemServer.cpp
● Path: frameworks/base/services/jni/
● namespace: Android
● C, C++, java, JNI:
○ com/android/server/SystemServer.java
○ com_android_server_SystemServer.cpp
○ Note: Name convention should suffice.
However, when adding to the SystemServer, it is advised to also
jniRegisterNativeMethods (@see libnativehelper/…)
● As per the code itself…
static void android_server_SystemServer_nativeInit(JNIEnv* env, jobject clazz) {
char propBuf[PROPERTY_VALUE_MAX];
property_get("system_init.startsensorservice", propBuf, "1");
if (strcmp(propBuf, "1") == 0) {
SensorService::instantiate(); // Start the sensor service which is pure native
} // @see frameworks/native/services/sensorservice
}
onload.cpp
● jint JNI_OnLoad(JavaVM* vm, void* reserved)
Called by default by the JVM upon System.loadLibrary()
● Loads the JNI Environment (uses JNI_VERSION_1_4)
● Registers native servers by calling
register_android_server_<Name>(env);
<Name> can be one of:
PowerManagerService SerialService
InputApplicationHandle InputWindowHandle
InputManager LightsService
AlarmManagerService UsbDeviceManager
UsbHostManager VibratorService
SystemServer location_GpsLocationProvider
location_FlpHardwareProvider connectivity_Vpn
AssetAtlasService ConsumerIrService
register_android_server_<Name>
and jniRegisterNativeMethods
● As we saw, libandroid_servers’s JNI_OnLoad() registers
each of the JNI servers.
● Each explicitly registers the exported JNI constructs,
by providing their signatures to libnativehelper’s
jniRegisterNativeMethods() method
● Which in turns calls JNI’s RegisterNatives() method.
● This is also essential because the AOSP uses naming
conventions that do not start with the “Java_” prefix, and
therefore cannot be invoked unless explicitly
registered by RegisterNatives()
JNI_onLoad()
● The context of the VM is available only in the
called thread.
● Which means that calling back Java is
possible only if:
○ It is a call back from a thread invoked by Java
○ Somewhere a reference is stored globally for all/for
relevant threads
● Do JVM caching on onLoad()
● Free on onUnload()
Part III
Writing an Android App
PSCG
Native project directory structure
● Source Control:
○ ./ - Root. Home of manifest, ant/gradle, ...
○ src - Java source files
○ lib - Libaries. Including generated libraries and .so’s
○ res - Resources
○ assets - Assets (raw resources etc.)
○ jni - Native code. Home of *.c*, *.h*, *.mk
■ Android.mk - Makefile
■ Application.mk - Application definition (APP_*)
● Generated
○ gen - generated java files
○ obj - Native object files
○ bin - Binaries
NDK App development with Android
1. Java code - as in Java’s JNI.
2. Native code - as in Java’s JNI
3. javah - provide class path (bin/…)
4. Makefiles
a. Android.mk - Android makefile.
i. e.g. include $(BUILD_SHARED_LIBRARY)
b. Application.mk - Application definitions
i. e.g. APP_ABI := all -
5. ndk-build - builds native code
6. ant/gradle - builds APK and bundles .so’s in
lib
Tutorial 2: DIY
HelloWorld
${NDK}/samples/hello-jni
jni/
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := hello-jni
LOCAL_SRC_FILES := hello-jni.c
include $(BUILD_SHARED_LIBRARY)
Application.mk
APP_ABI := x86 armeabi
obj/local/x86/libhello-jni.so
obj/local/armeabi/libhello-jni.so
ndk-build
src/
com/example/hellojni/HelloJni.java
package com.example.hellojni;
import android.app.Activity;
import android.widget.TextView;
import android.os.Bundle;
public class HelloJni extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView tv = new TextView(this);
tv.setText( stringFromJNI() );
setContentView(tv);
}
public native String stringFromJNI();
public native String unimplementedStringFromJNI(); // Catch: Call --> exception
static {
System.loadLibrary("hello-jni");
}
}
The Native App Glue
● Enables writing fully native applications
○ That is 0 java files
● Usually good for porting games
● Or porting other heavy event machine logic
● Requires implementation of your own Looper
● Requires a manifest declaration:
<activity android:name="android.app.NativeActivity"
android:label="@string/app_name"
android:configChanges="orientation|keyboardHidden">
<!-- Tell NativeActivity the name of or .so -->
<meta-data android:name="android.app.lib_name"
android:value="native-activity" />
...
Publishing Applications
● Two approaches each has its pros and cons
● The first: Compile with all the libraries you
can (APP_ABI := all)
○ Easier to maintain.
○ At the cost of larger (and sometimes huge) APK’s
● The second: Create version per architecture
○ Create application with a slightly modifed version
code at the MSB.
○ This is the PlayStore way of identifying multiple
APKs for the same version
References
● http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/types.html
● http://developer.android.com/tools/sdk/ndk/index.html
● Introduction to Android Internals - Ron Munitz, Afeka
● Native Android Programming course - @thePSCG
Thank You
PSCG

More Related Content

PDF
NDK Primer (AnDevCon Boston 2014)
Ron Munitz
 
PDF
Understanding the Dalvik bytecode with the Dedexer tool
Gabor Paller
 
PDF
Inc0gnito 2015 Android DEX Analysis Technique
남준 김
 
PDF
Java Presentation For Syntax
PravinYalameli
 
PDF
Tutorial c#
Mohammad Faizan
 
PDF
College Project - Java Disassembler - Description
Ganesh Samarthyam
 
PDF
LinkedIn - Disassembling Dalvik Bytecode
Alain Leon
 
PDF
1..Net Framework Architecture-(c#)
Shoaib Ghachi
 
NDK Primer (AnDevCon Boston 2014)
Ron Munitz
 
Understanding the Dalvik bytecode with the Dedexer tool
Gabor Paller
 
Inc0gnito 2015 Android DEX Analysis Technique
남준 김
 
Java Presentation For Syntax
PravinYalameli
 
Tutorial c#
Mohammad Faizan
 
College Project - Java Disassembler - Description
Ganesh Samarthyam
 
LinkedIn - Disassembling Dalvik Bytecode
Alain Leon
 
1..Net Framework Architecture-(c#)
Shoaib Ghachi
 

What's hot (20)

PPT
C Course Material0209
chameli devi group of institutions
 
PPTX
CSharp Presentation
Vishwa Mohan
 
PDF
2.Getting Started with C#.Net-(C#)
Shoaib Ghachi
 
PPT
Unit 2 Java
arnold 7490
 
PPTX
Let's talk about jni
Yongqiang Li
 
PDF
Core Java Certification
Vskills
 
PDF
The dedexer disassembler
Gabor Paller
 
PPTX
Java OOP Concepts 1st Slide
sunny khan
 
PPT
Csharp
Swaraj Kumar
 
PPT
C sharp
Satish Verma
 
PPTX
Dancing with dalvik
Thomas Richards
 
PPT
Java for C++ programers
Salahaddin University-Erbil
 
DOCX
Page List & Sample Material (Repaired)
Muhammad Haseeb Shahid
 
PPS
09 iec t1_s1_oo_ps_session_13
Niit Care
 
PDF
JNA - Let's C what it's worth
Idan Sheinberg
 
PPTX
Java Notes
Sreedhar Chowdam
 
PPS
Java session08
Niit Care
 
PPTX
Core Java Tutorials by Mahika Tutorials
Mahika Tutorials
 
PPT
Dot net introduction
Dr.Neeraj Kumar Pandey
 
C Course Material0209
chameli devi group of institutions
 
CSharp Presentation
Vishwa Mohan
 
2.Getting Started with C#.Net-(C#)
Shoaib Ghachi
 
Unit 2 Java
arnold 7490
 
Let's talk about jni
Yongqiang Li
 
Core Java Certification
Vskills
 
The dedexer disassembler
Gabor Paller
 
Java OOP Concepts 1st Slide
sunny khan
 
Csharp
Swaraj Kumar
 
C sharp
Satish Verma
 
Dancing with dalvik
Thomas Richards
 
Java for C++ programers
Salahaddin University-Erbil
 
Page List & Sample Material (Repaired)
Muhammad Haseeb Shahid
 
09 iec t1_s1_oo_ps_session_13
Niit Care
 
JNA - Let's C what it's worth
Idan Sheinberg
 
Java Notes
Sreedhar Chowdam
 
Java session08
Niit Care
 
Core Java Tutorials by Mahika Tutorials
Mahika Tutorials
 
Dot net introduction
Dr.Neeraj Kumar Pandey
 
Ad

Similar to NDK Primer (Wearable DevCon 2014) (20)

PPT
Android JNI
Siva Ramakrishna kv
 
PDF
Getting started with the JNI
Kirill Kounik
 
PDF
Using the Android Native Development Kit (NDK)
DroidConTLV
 
PDF
Introduction to the Android NDK
BeMyApp
 
PDF
109842496 jni
Vishal Singh
 
PPT
C++ programming with jni
Peter Hagemeyer
 
PDF
Native code in Android applications
Dmitry Matyukhin
 
PPTX
Android ndk
Khiem-Kim Ho Xuan
 
PPTX
Advance Android Application Development
Ramesh Prasad
 
PDF
Android and cpp
Joan Puig Sanz
 
PDF
NDK Programming in Android
Arvind Devaraj
 
PDF
NASAfinalPaper
Danish Vaid
 
PDF
Using the Android Native Development Kit (NDK)
Xavier Hallade
 
PDF
JNI - Java & C in the same project
Karol Wrótniak
 
PPTX
Using the android ndk - DroidCon Paris 2014
Paris Android User Group
 
PPTX
Native development kit (ndk) introduction
Rakesh Jha
 
PPTX
GOTO Night with Charles Nutter Slides
Alexandra Masterson
 
PDF
Inside JVM
Chinh Ngo Nguyen
 
PPTX
Android ndk
Sentinel Solutions Ltd
 
PPTX
Android NDK
Sentinel Solutions Ltd
 
Android JNI
Siva Ramakrishna kv
 
Getting started with the JNI
Kirill Kounik
 
Using the Android Native Development Kit (NDK)
DroidConTLV
 
Introduction to the Android NDK
BeMyApp
 
109842496 jni
Vishal Singh
 
C++ programming with jni
Peter Hagemeyer
 
Native code in Android applications
Dmitry Matyukhin
 
Android ndk
Khiem-Kim Ho Xuan
 
Advance Android Application Development
Ramesh Prasad
 
Android and cpp
Joan Puig Sanz
 
NDK Programming in Android
Arvind Devaraj
 
NASAfinalPaper
Danish Vaid
 
Using the Android Native Development Kit (NDK)
Xavier Hallade
 
JNI - Java & C in the same project
Karol Wrótniak
 
Using the android ndk - DroidCon Paris 2014
Paris Android User Group
 
Native development kit (ndk) introduction
Rakesh Jha
 
GOTO Night with Charles Nutter Slides
Alexandra Masterson
 
Inside JVM
Chinh Ngo Nguyen
 
Ad

Recently uploaded (20)

PPTX
slidesgo-unlocking-the-code-the-dynamic-dance-of-variables-and-constants-2024...
kr2589474
 
PPTX
Web Testing.pptx528278vshbuqffqhhqiwnwuq
studylike474
 
PPTX
PFAS Reporting Requirements 2026 Are You Submission Ready Certivo.pptx
Certivo Inc
 
PDF
An Experience-Based Look at AI Lead Generation Pricing, Features & B2B Results
Thomas albart
 
PDF
WatchTraderHub - Watch Dealer software with inventory management and multi-ch...
WatchDealer Pavel
 
PDF
Exploring AI Agents in Process Industries
amoreira6
 
PDF
Bandai Playdia The Book - David Glotz
BluePanther6
 
PDF
Teaching Reproducibility and Embracing Variability: From Floating-Point Exper...
University of Rennes, INSA Rennes, Inria/IRISA, CNRS
 
PPTX
Maximizing Revenue with Marketo Measure: A Deep Dive into Multi-Touch Attribu...
bbedford2
 
PDF
49784907924775488180_LRN2959_Data_Pump_23ai.pdf
Abilash868456
 
PDF
lesson-2-rules-of-netiquette.pdf.bshhsjdj
jasmenrojas249
 
PPTX
ConcordeApp: Engineering Global Impact & Unlocking Billions in Event ROI with AI
chastechaste14
 
PPTX
Presentation about Database and Database Administrator
abhishekchauhan86963
 
PPTX
Presentation about variables and constant.pptx
kr2589474
 
PPTX
oapresentation.pptx
mehatdhavalrajubhai
 
PPTX
Odoo Integration Services by Candidroot Solutions
CandidRoot Solutions Private Limited
 
PDF
Download iTop VPN Free 6.1.0.5882 Crack Full Activated Pre Latest 2025
imang66g
 
PDF
Balancing Resource Capacity and Workloads with OnePlan – Avoid Overloading Te...
OnePlan Solutions
 
PPTX
Can You Build Dashboards Using Open Source Visualization Tool.pptx
Varsha Nayak
 
PPTX
Explanation about Structures in C language.pptx
Veeral Rathod
 
slidesgo-unlocking-the-code-the-dynamic-dance-of-variables-and-constants-2024...
kr2589474
 
Web Testing.pptx528278vshbuqffqhhqiwnwuq
studylike474
 
PFAS Reporting Requirements 2026 Are You Submission Ready Certivo.pptx
Certivo Inc
 
An Experience-Based Look at AI Lead Generation Pricing, Features & B2B Results
Thomas albart
 
WatchTraderHub - Watch Dealer software with inventory management and multi-ch...
WatchDealer Pavel
 
Exploring AI Agents in Process Industries
amoreira6
 
Bandai Playdia The Book - David Glotz
BluePanther6
 
Teaching Reproducibility and Embracing Variability: From Floating-Point Exper...
University of Rennes, INSA Rennes, Inria/IRISA, CNRS
 
Maximizing Revenue with Marketo Measure: A Deep Dive into Multi-Touch Attribu...
bbedford2
 
49784907924775488180_LRN2959_Data_Pump_23ai.pdf
Abilash868456
 
lesson-2-rules-of-netiquette.pdf.bshhsjdj
jasmenrojas249
 
ConcordeApp: Engineering Global Impact & Unlocking Billions in Event ROI with AI
chastechaste14
 
Presentation about Database and Database Administrator
abhishekchauhan86963
 
Presentation about variables and constant.pptx
kr2589474
 
oapresentation.pptx
mehatdhavalrajubhai
 
Odoo Integration Services by Candidroot Solutions
CandidRoot Solutions Private Limited
 
Download iTop VPN Free 6.1.0.5882 Crack Full Activated Pre Latest 2025
imang66g
 
Balancing Resource Capacity and Workloads with OnePlan – Avoid Overloading Te...
OnePlan Solutions
 
Can You Build Dashboards Using Open Source Visualization Tool.pptx
Varsha Nayak
 
Explanation about Structures in C language.pptx
Veeral Rathod
 

NDK Primer (Wearable DevCon 2014)

  • 1. NDK Primer Ron Munitz Founder & CEO - The PSCG Founder & CTO - Nubo [email protected] [email protected] https://github.com/ronubo/ Wearables DevCon March 2014 @ronubo PSCG
  • 2. This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. To view a copy of this license, visit http://creativecommons.org/licenses/by- sa/4.0/ © Copyright Ron Munitz 2014 PSCG
  • 3. About://Ron Munitz ● Distributed Fault Tolerant Avionic Systems ○ Linux, VxWorks, very esoteric libraries, 0’s and 1’s ● Highly distributed video routers ○ Linux ● Real Time, Embedded, Server bringups ○ Linux, Android , VxWorks, Windows, devices, BSPs, DSPs,... ● Distributed Android ○ Rdroid? Cloudroid? Too busy working to get over the legal naming, so no name is officially claimed for my open source ● What currently keeps me busy: ○ Running the PSCG, a Embedded/Android consulting and Training ○ Managing R&D at Nubo ○ Lecturing at Afeka’s college of Engineering ○ Amazing present, endless opportunities. (Wish flying took less time) @ronubo PSCG
  • 4. Agenda ● Part I: Java ○ Java Native Interface (JNI) - Theory ○ Hello World Tutorial - Practice ● Part II: JNI in the AOSP ● Part III: Native Android Apps
  • 5. Part I The Java Native Interface PSCG
  • 6. Introduction The JNI is a native programming interface. It allows Java code that runs inside a Java Virtual Machine (VM) to interoperate with applications and libraries written in other programming languages, such as C, C++, and assembly. All JVM implementation need to implement the JNI specification to allow compatibility with native code libraries. JNI to Java ⇔ __asm to C
  • 7. Motivation ● The standard Java class library does not support the platform-dependent features needed by the application. ○ For example NEON, SSSE3, ... ● You already have a library written in another language, and wish to make it accessible to Java code through the JNI. ● You want to implement a small portion of time-critical code in a lower-level language such as assembly.
  • 8. Wearable Motivation ● Reduce CPU cycles (and battery drain rate!) on intensive computations ● Add designated features for simple add-on hardware without having to support an entire ecosystem for that ● Media processing in Android: All is being done natively this way or another ● Porting legacy code ● Protecting your logic and algorithms from rev-eng
  • 9. JNI Pitfalls ● Subtle errors in the use of JNI can destabilize the entire JVM in ways that are very difficult to reproduce and debug. ● An application that relies on JNI loses the platform portability Java offers (a partial workaround is to write a separate implementation of JNI code for each platform and have Java detect the operating system and load the correct one at runtime). ● The JNI framework does not provide any automatic garbage collection for non-JVM memory resources allocated by code executing on the native side. Consequently, native side code (such as assembly language) must assume the responsibility for explicitly releasing any such memory resources that it itself acquires.
  • 11. JNI environment pointers The JNI interface is organized like a C++ virtual function table. It enables a VM to provide multiple versions of JNI function tables. The JNI interface pointer is only valid in the current thread. Native methods receive the JNI interface pointer as an argument. The VM is guaranteed to pass the same interface pointer to a native method when it makes multiple calls to the native method from the same Java thread.
  • 12. Loading and linking native methods Native methods are loaded with the System.loadLibrary() method. In the following example, the class initialization method loads a platform- specific native library in which the native method f is defined: class Cls { native boolean f(int i, String s); static { System.loadLibrary(“pkg_Cls”); } } The library pkg_Cls is platform specific. On a Unix derived system it will be named libpkg_Cls.so and on windows system it will be named pkg_Cls.dll.
  • 13. Loading and linking native methods (cont.) Dynamic linkers resolve entries based on their 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 The signature of function f above is, as created by javah: JNIEXPORT jboolean JNICALL Java_Cls_f(JNIEnv *, jobject, jint, jstring); JNIEnv * - pointer to the JNI interface jobject - a pointer to the calling java class for a static method or a pointer to the calling java object for non-static method.
  • 14. Referencing java objects ● Primitive types, such as integers, characters, and so on, are copied between Java and native code (call by value) ● Arbitrary Java objects, on the other hand, are passed by reference. ● The VM must keep track of all objects that have been passed to the native code, so that these objects are not freed by the garbage collector. ● The native code, in turn, must have a way to inform the VM that it no longer needs the objects. ● The JNI divides object references used by the native code into two categories: local and global references. ○ Local references are valid for the duration of a native method call, and are automatically freed after the native method returns. ○ Global references remain valid until they are explicitly freed.
  • 15. Referencing java objects (Cont.) ● Objects are passed to native methods as local references. All Java objects returned by JNI functions are local references. ● The JNI allows the programmer to create global references from local references. JNI functions that expect Java objects accept both global and local references. A native method may return a local or global reference to the VM as its result. ● Since the VM needs a certain amount of space to keep track of a local reference, creating too many local references may cause the system to run out of memory. ● Local references are only valid in the thread in which they are created. ● Local references are automatically garbage collected once the function returns.
  • 16. Invocation API Used to call java from c/c++ code. The JNI interface pointer (JNIEnv) is valid only in the current thread. Should another thread need to access the Java VM, it must first call AttachCurrentThread() to attach itself to the VM and obtain a JNI interface pointer. Once attached to the VM, a native thread works just like an ordinary Java thread running inside a native method. The native thread remains attached to the VM until it calls DetachCurrentThread() to detach itself.
  • 17. Accessing fields and methods ● The JNI allows native code to access the fields and to call the methods of Java objects. ● The JNI identifies methods and fields by their symbolic names and type signatures. ● A two-step process factors out the cost of locating the field or method from its name and signature. For example, to call the method f in class cls, the native code first obtains a method ID, as follows: jmethodID methodId = env->GetMethodID(cls, “f”, “(ILjava/lang/String;)D”); The native code can then use the method ID repeatedly without the cost of method lookup, as follows: jdouble result = env->CallDoubleMethod(obj, methodID, 10, str);
  • 18. Exception handling There are two ways to handle an exception in native code: ● The native method can choose to return immediately, causing the exception to be thrown in the Java code that initiated the native method call. ● The native code can clear the exception by calling ExceptionClear(), and then execute its own exception-handling code. After an exception has been raised, the native code must first clear the exception before making other JNI calls.
  • 19. JNI types and data structures Java Type Native Type Description boolean jboolean unsigned 8 bits byte jbyte signed 8 bits char jchar unsigned 16 bits short jshort signed 16 bits int jint signed 32 bits long jlong signed 64 bits float jfloat 32 bits double jdouble 64 bits
  • 20. JNI types and data structures
  • 21. JVM Type Signatures Type Signature Java Type Z boolean B byte C char S short I int J long F float D double L fully-qualified-class ; fully-qualified-class [ type type[] ( arg-types ) ret-type method type For example, the Java method: long f(int n, String s, int[] arr); has the following type signature: (ILjava/lang/String;[I)J
  • 22. JNI types and data structures Java Type Native Type Description boolean jboolean unsigned 8 bits byte jbyte signed 8 bits char jchar unsigned 16 bits short jshort signed 16 bits int jint signed 32 bits long jlong signed 64 bits float jfloat 32 bits double jdouble 64 bits
  • 23. JNI types and data structures
  • 25. Step 1: HelloWorld.java class HelloWorld { private native void print(); public static void main(String[] args) { new HelloWorld().print(); } static { System.loadLibrary("HelloWorld"); // Note: No “lib”, No “.so”. } } Compile: javac HelloWorld.java . Run: java HelloWorld Fail: java.lang.UnsatisfiedLinkError: no HelloWorld in java.library.path . Not surprising…
  • 26. Step 2: Auto Generate Headers ~/edu/jni$ javah HelloWorld # Note: javah takes a class name :~/edu/jni$ cat HelloWorld.h /* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class HelloWorld */ #ifndef _Included_HelloWorld #define _Included_HelloWorld #ifdef __cplusplus extern "C" { #endif /* Class: HelloWorld Method: print Signature: ()V */ JNIEXPORT void JNICALL Java_HelloWorld_print (JNIEnv *, jobject); // “Java” - because I didn’t use a package. #ifdef __cplusplus } #endif #endif
  • 27. Step 3: HelloWorld.c #include <stdio.h> #include "HelloWorld.h" JNIEXPORT void JNICALL Java_HelloWorld_print (JNIEnv *env, jobject obj) { printf("Hello World!n"); } Compile: gcc -shared -fPIC -I<YourJvmIncludePaths> HelloWorld.c -o libHelloWorld.so Run: In a couple of slides. Fail: Easily. GCC flags are subtle.
  • 28. Step 3.5: Build the Shared Library Let’s have a look at the following concrete example: gcc -shared -fPIC -I/usr/lib/jvm/jdk1.7.0/include/linux -I/usr/lib/jvm/jdk1.7.0/include HelloWorld.c -o libHelloWorld.so -shared: Create a shared object. (In Windows: a “DLL”) -fPIC: Position Independent Code - Always create Shared Object with that flag. -I<et. al>: Location of jni.h, and files included from there. -o libHelloWorld.so: Everything between “lib” and “.so” must match the name in loadLibrary().
  • 29. Step 4: Run java -Djava.library.path=. HelloWorld Note: It is important to tell java where to look for your shared libraries. Otherwise you will see the same error listed in Step 1. Hello World!
  • 30. Part II SystemServer’s native side: libandroid_services PSCG
  • 31. The NDK in a nutshell ● Available as a JNI “SDK” to Android application developers. ○ In the platform itself there is no need for it, just as there is no need for the Android SDK ● Eases porting of existing Linux code to Android ○ As long as it is not heavily depended on glibc features, X, QT/GTK etc. ● Enables common code for multiple architectures ○ On the nominal portable C/C++ code case ○ @see Application.mk
  • 32. JNI in the Android platform ● @see frameworks/base/services/java/com/android/server/SystemServer.java ● This is where the Java Android OS starts. ● And it is heavily relying on native functions
  • 33. SystemServer.java revisited public class SystemServer { private static final String TAG = "SystemServer"; //... private static native void nativeInit(); /*Called to initialize native system services.*/ public static void main(String[] args) { // ... // Set runtime libary property (Dalvik/ART/..) ... // Set initial system time (to workaround some negative value bugs) ... // Enable profiler snapshot if profiler is enabled ... // Take care of HeapSize for the System Server which never dies ... // ... System.loadLibrary("android_servers"); Slog.i(TAG, "Entered the Android system server!"); nativeInit(); /* Initializes native services - This is a JNI call to frameworks/base/services/jni/com_android_server_SystemServer.cpp … See next slide*/ ServerThread thr = new ServerThread(); thr.initAndLoop(); // Note to self: so long init2()!!! } }
  • 34. com_android_server_SystemServer.cpp ● Path: frameworks/base/services/jni/ ● namespace: Android ● C, C++, java, JNI: ○ com/android/server/SystemServer.java ○ com_android_server_SystemServer.cpp ○ Note: Name convention should suffice. However, when adding to the SystemServer, it is advised to also jniRegisterNativeMethods (@see libnativehelper/…) ● As per the code itself… static void android_server_SystemServer_nativeInit(JNIEnv* env, jobject clazz) { char propBuf[PROPERTY_VALUE_MAX]; property_get("system_init.startsensorservice", propBuf, "1"); if (strcmp(propBuf, "1") == 0) { SensorService::instantiate(); // Start the sensor service which is pure native } // @see frameworks/native/services/sensorservice }
  • 35. onload.cpp ● jint JNI_OnLoad(JavaVM* vm, void* reserved) Called by default by the JVM upon System.loadLibrary() ● Loads the JNI Environment (uses JNI_VERSION_1_4) ● Registers native servers by calling register_android_server_<Name>(env); <Name> can be one of: PowerManagerService SerialService InputApplicationHandle InputWindowHandle InputManager LightsService AlarmManagerService UsbDeviceManager UsbHostManager VibratorService SystemServer location_GpsLocationProvider location_FlpHardwareProvider connectivity_Vpn AssetAtlasService ConsumerIrService
  • 36. register_android_server_<Name> and jniRegisterNativeMethods ● As we saw, libandroid_servers’s JNI_OnLoad() registers each of the JNI servers. ● Each explicitly registers the exported JNI constructs, by providing their signatures to libnativehelper’s jniRegisterNativeMethods() method ● Which in turns calls JNI’s RegisterNatives() method. ● This is also essential because the AOSP uses naming conventions that do not start with the “Java_” prefix, and therefore cannot be invoked unless explicitly registered by RegisterNatives()
  • 37. JNI_onLoad() ● The context of the VM is available only in the called thread. ● Which means that calling back Java is possible only if: ○ It is a call back from a thread invoked by Java ○ Somewhere a reference is stored globally for all/for relevant threads ● Do JVM caching on onLoad() ● Free on onUnload()
  • 38. Part III Writing an Android App PSCG
  • 39. Native project directory structure ● Source Control: ○ ./ - Root. Home of manifest, ant/gradle, ... ○ src - Java source files ○ lib - Libaries. Including generated libraries and .so’s ○ res - Resources ○ assets - Assets (raw resources etc.) ○ jni - Native code. Home of *.c*, *.h*, *.mk ■ Android.mk - Makefile ■ Application.mk - Application definition (APP_*) ● Generated ○ gen - generated java files ○ obj - Native object files ○ bin - Binaries
  • 40. NDK App development with Android 1. Java code - as in Java’s JNI. 2. Native code - as in Java’s JNI 3. javah - provide class path (bin/…) 4. Makefiles a. Android.mk - Android makefile. i. e.g. include $(BUILD_SHARED_LIBRARY) b. Application.mk - Application definitions i. e.g. APP_ABI := all - 5. ndk-build - builds native code 6. ant/gradle - builds APK and bundles .so’s in lib
  • 42. jni/ Android.mk LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := hello-jni LOCAL_SRC_FILES := hello-jni.c include $(BUILD_SHARED_LIBRARY) Application.mk APP_ABI := x86 armeabi obj/local/x86/libhello-jni.so obj/local/armeabi/libhello-jni.so ndk-build
  • 43. src/ com/example/hellojni/HelloJni.java package com.example.hellojni; import android.app.Activity; import android.widget.TextView; import android.os.Bundle; public class HelloJni extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); TextView tv = new TextView(this); tv.setText( stringFromJNI() ); setContentView(tv); } public native String stringFromJNI(); public native String unimplementedStringFromJNI(); // Catch: Call --> exception static { System.loadLibrary("hello-jni"); } }
  • 44. The Native App Glue ● Enables writing fully native applications ○ That is 0 java files ● Usually good for porting games ● Or porting other heavy event machine logic ● Requires implementation of your own Looper ● Requires a manifest declaration: <activity android:name="android.app.NativeActivity" android:label="@string/app_name" android:configChanges="orientation|keyboardHidden"> <!-- Tell NativeActivity the name of or .so --> <meta-data android:name="android.app.lib_name" android:value="native-activity" /> ...
  • 45. Publishing Applications ● Two approaches each has its pros and cons ● The first: Compile with all the libraries you can (APP_ABI := all) ○ Easier to maintain. ○ At the cost of larger (and sometimes huge) APK’s ● The second: Create version per architecture ○ Create application with a slightly modifed version code at the MSB. ○ This is the PlayStore way of identifying multiple APKs for the same version