SlideShare a Scribd company logo
1 of 45
Download to read offline
Tips and Tricks for
Building
High-Performance
Android Apps
using Native Code
Kenneth Geisshirt
kg@realm.io
Realm Inc.
@realm
http://github.com/Realm/
http://realm.io/
JD Hancock: Reign of The Android. http://bit.ly/1GN8vmg
Swen-Peter Ekkebus: Goal! http://bit.ly/1x1suYm
Avinash Sharma: http://bit.ly/1aRorcH
• Android development is not just
Java
• C and C++ can speed apps up
- and reuse old legacy code
• Learn a few tricks when
working with Java Native
Interface
• Hands-on exercises
Today’s Goal
Agenda
• Setting up your environment
• Java Native Interface
Exploratorium. After Dark: Time http://bit.ly/1aSQxo0
• Threading
• Using non-NDK libraries1
• Benchmarking
• Debugging
1NDK = Native Development Kit
Advantages
• Use C or C++ in your apps → no JIT needed as
always machine instructions
• Access to system calls (like mmap())
• Almost no limits on memory usage
• OpenGL programming
• Sharing code across platforms
• Reusing legacy libraries
Alan Bates. Good Times http://bit.ly/1BXX7FN
Disadvantages
• C and C++ memory
management → easy to crash
your app
• And debugging across
languages is hard
• Bionic C library isn’t the GNU C library
• Doing a native call is expensive (in time)
• Cumbersome to use non-NDK libraries
Rocher: That_Sux http://bit.ly/1BdGNhJ
Use Cases
• AndEngine (2D Game Engine)
http://www.andengine.org
• ImageMagick for Android
https://github.com/paulasiimwe/Android-ImageMagick
• LevelDB for Android
https://github.com/litl/android-leveldb
• Support Vector Machine for Android
https://github.com/cnbuff410/Libsvm-androidjni
See-ming Lee; Rainbow Teddy shows BBF Stitch how
to use the Canon EOS M; http://bit.ly/1O3yA43
Playing with C++
Example: estimating π
Estimating π using dart
• Throw arrows at random
• Nhit/N = A/4 (quarter of a circle)
• A = π·r2 (area of a circle)
• π = 4·Nhit/N (with r = 1)
Bogdan Suditu: Darts. http://bit.ly/18jCExj
for i = 1,..,N
x = random(0, 1)
y = random(0, 1)
if (sqrt(x·x+y·y) < 1)
Nhit = Nhit +1
π = 4·Nhit/N
Example: the classes
Random number generator
• Constructor with seed
• Method uniform() to
return random number
between 0.0 and 1.0
π estimator
• Constructor with
number of iteration
• Method estimate() to
calculate the value of π
Quinn Dombrowski: Pi http://bit.ly/1Kz55cp
jeramiah.andrick. My random number generator http://bit.ly/1wbTbP2
• Implement two C++ classes
1. RNG - a random number generator
• uniform() returns a number in [0, 1[
2. pi - a π estimator using MC algorithm
• estimate() returns π
• Write simple test program
• Compile using clang++ or g++
• Go to https://github.com/kneth/AndroidCalcPi if lazy 😄
• Branch: initial
Exercise 1
The environment
• Android Studio 1.3.0 (July 28, 2015)
• Java 1.8 JDK
• or set version (▶ Build ▶ Build types)
• Android SDK 24.3.3
• Android NDK can now be bundled
• Gradle 2.5
• gradle-wrapper.properties
• A rooted device is nice to have
• Always use Intel HAXM for the emulator
Dave Gingrich;http://bit.ly/1HxRJWj
ndk.dir=/usr/local/Cellar/android-sdk/24.3.3/ndk-bundle
sdk.dir=/usr/local/Cellar/android-sdk/23.0.2
local.properties
Java Native Interface
Architecture
MainActivity.java
RNG.java Pi.java
net_zigzak_calcpi_
NativeRNG.{h,cpp}
net_zigzak_calcpi_
NativePi.{h,cpp}
pi.{hpp,cpp}rng.{hpp,cpp}
The Android App
Java wrapper classes
Intermediate C++ functions
Original C++ classes
Organize your files
• Use the experimental Android plugin for Gradle
• Place C/C++ files in app/src/main/jni/
• Add ndk.dir to local.properties
• Add an ndk section to your app’s
build.gradle
android.ndk {
moduleName = "calcPi"
cppFlags += ["-fexceptions"]
stl = "gnustl_shared" // for exceptions
}
Building and Loading your
native code
• Automatically build for all
supported architectures (ARM,
ARMv7, ARM64, MIPS, MIPS64,
x86, x86-64)
• Android only installs the relevant
architecture
• Load native code early (main
activity’s onCreate)
System.loadLibrary("calcPi");
The module name (from build.gradle)
Thomas Hawk: Loading Zone http://bit.ly/1MoBk9S
Calling a C++ function
• Use Java’s native keyword in
the signature
• Implement the function in C++
• Use a long to store the C++
pointer when you creates an
object
lamont_cranston: call center http://bit.ly/1A4JlK5
native long nativeCreate(long iterations);
native double nativeEstimate(long nativePtr);
Tell the Java compiler
it’s a native function
Returns a pointer
(a C++ object) Operates on a C++ object
Generate header files
• .class files contain information
about native calls
• javah can extract signatures and
generate C/C++ header files
Paul: Generator Room Door http://bit.ly/1C3SSs7
!/bin/bash
# Setting up
CLASSDIR="$(pwd)/../app/build/intermediates/classes/debug"
JNIDIR="$(pwd)"
# Generate the headers
(cd "$CLASSDIR" && javah -jni -classpath "$CLASSDIR" -d "$JNIDIR"
net.zigzak.androidcalcpi.NativePi net.zigzak.androidcalcpi.NativeRNG)
# Remove "empty" header files (they have 13 lines)
wc -l "$JNIDIR"/*.h | grep " 13 " | awk '{print $2}' | xargs rm -f
Classes to extract from
Add path to jar files you depend on
Java types in C/C++
• Java types are mapped to C/C++
types
• Convert Date to long before call
• Pass pointers over as long/
jlong
Java C/C++
long jlong
String jstring
long[] jlongArray
Object jObject
float jfloat
JNIEXPORT jdouble JNICALL Java_net_zigzak_androidcalcpi_NativePi_nativeEstimate
(JNIEnv *, jobject, jlong nativePtr)
{
Pi *pi = reinterpret_cast<Pi *>(nativePtr);
double estimate = pi->estimate();
return estimate;
}
Generated function name
cast to a proper C++ pointer
The pointer
Define as a macro if used often:
#define P(x) reinterpret_cast<Pi *>(x)
Working with arrays
• Copy values from
JVM memory to C/C
++ memory
• Remember to free
C/C++ memory →
avoid memory leaks
jsize arr_len = env->GetArrayLength(columnIndexes);
jlong *arr = env->GetLongArrayElements(columnIndexes, NULL);
// use the elements of arr
env->ReleaseLongArrayElements(columnIndexes, arr, 0);
• Create a new
Java array
• Copy C/C++ array
to Java array
jArray = env->NewByteArray(jlen);
if (jArray)
// Copy data to Byte[]
env->SetByteArrayRegion(jArray, 0, jlen,
reinterpret_cast<const jbyte*>(bufPtr));
free(bufPtr);
return jArray;
Strings as trouble-makers• Java strings are in modified UTF-8
• null character encoded as 0xC0 0x80 (not valid UTF-8)
• Many C/C++ libraries assume plain UTF-8
jchar stack_buf[stack_buf_size];
// adding characters to stack_bf
jchar* out_begin = stack_buf;
if (int_cast_with_overflow_detect(out_curr - out_begin, out_size))
throw runtime_error("String size overflow");
return env->NewString(out_begin, out_size);
jstring s; // typical a JNI function parameter
jchar *c = e->GetStringChars(s, 0);
// use c
env->ReleaseStringChars(s, c);
Create a new Java string
• Copy Java string to C/C++ array
• Remember to deallocate C array
Exercise 2
• Create a simple Android app
• Implement Java classes RNG and Pi
• Generate header files
• Implement intermediate C++ function and call original
C++ code
• Go to https://github.com/kneth/AndroidCalcPi if lazy 😄
• branch wrapping
C++ exceptions
• C++ code can throw exceptions
• new can throw bad_alloc,etc.
• If uncaught the app crashes with hard-to-
understand messages in the log
Build fingerprint: 'generic_x86/sdk_x86/generic_x86:4.4.2/KK/999428:eng/test-keys'
Revision: '0'
pid: 1890, tid: 1890, name: t.zigzak.calcpi >>> net.zigzak.calcpi <<<
signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
eax 00000000 ebx 00000762 ecx 00000762 edx 00000006
esi 00000762 edi 0000000b
xcs 00000073 xds 0000007b xes 0000007b xfs 00000000 xss 0000007b
eip b7707c96 ebp b776cce0 esp bfa22090 flags 00200203
backtrace:
#00 pc 0003bc96 /system/lib/libc.so (tgkill+22)
#01 pc 00000005 <unknown>
stack:
bfa22050 00000001
bfa22054 b899c6d0 [heap]
bfa22058 00000015
bfa2205c b76d9ef9 /system/lib/libc.so (pthread_mutex_unlock+25)
bfa22060 a73bfd19 /data/app-lib/net.zigzak.calcpi-1/libgnustl_shared.so
bfa22064 b7767fcc /system/lib/libc.so
• Better solution:
• catch and
rethrow as
Java exception
Throwing a Java exception
• You don’t throw an exception
• You set the “exception” state in the
JVM
• Return from C/C++ function
try {
Pi *pi = new Pi(static_cast<long>(iterations));
return reinterpret_cast<jlong>(pi);
}
catch (std::exception& e) {
jclass jExceptionClass =
env->FindClass("java/lang/RuntimeException");
std::ostringstream message;
message << "Allocating native class Pi failed: " << e.what();
env->ThrowNew(jExceptionClass, message.str().c_str());
env->DeleteLocalRef(jExceptionClass);
}
return 0;
" Get a reference to the exception
# Set the “exception” state
$ Clean up
followtheinstructrions: hand werpen http://bit.ly/1Bo3gZx
Logging
• JNI provides access to the Android log
• __android_log_print is a simple
variadic log function
• Linking with liblog is required
• size_t depends on bit width → cast
to int64_t before logging
vitelone: Deck Log Book http://bit.ly/1AXKZ0j
android.ndk {
moduleName = "calcPi"
cppFlags += ["-fexceptions"]
ldLibs += ["log"]
stl = "gnustl_shared" // for exceptions
}
Link flag
#define LOG(...) __android_log_print(ANDROID_LOG_DEBUG, "calcPi", __VA_ARGS__);
Macro to simplify logging
Tracing JNI calls
• It is useful the trace calls
• Define ENTER, ENTER_PTR, and LEAVE macros
• Logging native pointer as jlong often produce
negative numbers - don’t worry
1955-1955/net.zigzak.calcpi D/calcPi﹕ Enter Java_net_zigzak_calcpi_NativePi_nativeCreate
1955-1955/net.zigzak.calcpi D/calcPi﹕ iterations: 10000
1955-1955/net.zigzak.calcpi D/calcPi﹕ Enter Java_net_zigzak_calcpi_NativePi_nativeEstimate
-1202665872
1955-1955/net.zigzak.calcpi D/calcPi﹕ estimate = 3.128400e+00
Exercise 3
• Catch common C++ exceptions (bad_alloc)
• Rethrow as a Java exception
• Adding logging/tracing of JNI calls
• Go to https://github.com/kneth/AndroidCalcPi if
lazy 😄
• branch exceptions-and-logging
Tricks to compiling
and linking
Reduce size
• Compiler can optimise for size (-Os)
• Link Time Optimizations (LTO) can reduce size of native code
• Eliminate unused code (-ffunction-sections -fdata-
sections) and unused ELF symbols (-
fvisibility=hidden)
android.ndk {
moduleName = "calcPi"
cppFlags += ["-Os", "-fexceptions", "-fvisibility=hidden"
"-ffunction-sections", "-fdata-sections",
"-Wl,--gc-sections", "-flto"]
ldLibs += "log"
stl = "gnustl_shared" // for exceptions
ldFlags += ["-Wl,--gc-sections", "-flto"] // reduce size
}
http://realm.io/news/reducing-apk-size-native-libraries/
Threading
POSIX threads
• Android’s Bionic C library supports POSIX threads
• except cancellation
• Threading can utilize your device’s cores
• If you utilize all cores for longer times, you get
W/art﹕ Suspending all threads took: 40.036ms
I/Choreographer﹕ Skipped 18858 frames! The application may be doing
too much work on its main thread.
Exercise 4
• Add a π estimator using POSIX threads
• reuse the estimate method
• Go to https://github.com/kneth/AndroidCalcPi if
lazy 😄
• branch posix-threads
Using non-NDK
libraries
Libraries
• NDK has some libraries
• Basic ones: standard C, logging, etc.
• Linked during build
• Android has many other libraries
• /system/lib is their home
• OpenSSL, XML2, SQLite, ICU
How to use?
• Android has dynamic linking
• Add dl to ldFlags
• Include dlfcn.h in your C/C++ files
• You might have to declare relevant structs and
types
SHA256_CTX ctx;
int (*SHA224_Init)(SHA256_CTX *);
SHA224_Init =
reinterpret_cast<int (*)(SHA256_CTX*)>
(dlsym(RTLD_DEFAULT, “SHA224_Init”));
SHA224_Init(&ctx);
Function pointer
Find symbol
in .so file
Exercise 5
• Add method to a class
• Load one or two libcrypto functions
• and call them
• Go to https://github.com/kneth/AndroidCalcPi if
lazy 😄
• branch non-ndk-libraries
Benchmarking
What makes benchmarking
hard?
• Android devices do many things
• checking for updates,
synchronising accounts, garbage
collection, etc.
• Android timers are not reliable
• Just-in-Time compilation
William Warby, Triple Timer; http://bit.ly/1TwetP4
Measuring timer resolution
• Use
Debug.threadCpuTimeNano
s()
• But resolution depends on
device
• Microbenchmark must be
longer than resolution
• Resolution is used to validate
benchmark
• Go to https://github.com/kneth/
AndroidCalcPi
• branch benchmarking
long diff = 50000;
for (int i = 0; i < 100; i++) {
long end;
long start =
Debug.threadCpuTimeNanos();
while (true) {
end = Debug.threadCpuTimeNanos();
if (end != start) {
if (diff > (end - start)) {
diff = end - start;
}
break;
}
}
}
Debugging
Android Debug Bridge
• Android Debug Bridge (adb) has
some useful subcommands
• shell: plain command-line shell
• pull: copy file from device
• push: copy file to device
M. O’Thompsonski, http://bit.ly/1Da0o0h
Get stack trace
• Android apps are processes
• Dump stack traces using
kill
• Log every native call
mkdir -p /data/anr
ps # find your app
kill -3 <pid>
cat /data/anr/traces.txt
#define ENTER_PTR(ptr)
__android_log_print(ANDROID_LOG_DEBUG,"calcPi", "Enter %s %" PRId64,
__FUNCTION__, static_cast<int64_t>(ptr));
Forces 64 bit value!
The name of the function
Checking native memory
• The emulator can help checking
malloc
• C/C++ makes it easy to do
memory management wrong
• Set the debug level to 20
adb shell setprop libc.debug.malloc 20
adb shell stop
adb shell start
Steve Jurvetson, Primitive Memories; http://bit.ly/1HY80sf
Native debugging
• Android Studio 1.3 supports native debugging
• gdb or lldb
• Add a run configuration (native)
android.buildTypes {
debug {
isJniDebuggable = true
isDebuggable = true
}
}
App’s build.grade
References
• High Performance Android Apps by Doug Sillars.
O’Reilly Media, 2015.
• Essential JNI by Rob Gordon. Prentice Hall, 1998.
• The Java Native Interface by Sheng Liang.
Addison-Wesley, 1999.
• Android NDK by Sylvian Rataboil. Packt Publishing,
2012.
Build High-Performance Android Apps with Native Code

More Related Content

What's hot

Øredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...
Øredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...Øredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...
Øredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...Charles Nutter
 
Understanding Javascript Engines
Understanding Javascript Engines Understanding Javascript Engines
Understanding Javascript Engines Parashuram N
 
Node.js/io.js Native C++ Addons
Node.js/io.js Native C++ AddonsNode.js/io.js Native C++ Addons
Node.js/io.js Native C++ AddonsChris Barber
 
Virtual machine and javascript engine
Virtual machine and javascript engineVirtual machine and javascript engine
Virtual machine and javascript engineDuoyi Wu
 
What to expect from Java 9
What to expect from Java 9What to expect from Java 9
What to expect from Java 9Ivan Krylov
 
Unleash your inner console cowboy
Unleash your inner console cowboyUnleash your inner console cowboy
Unleash your inner console cowboyKenneth Geisshirt
 
Code lifecycle in the jvm - TopConf Linz
Code lifecycle in the jvm - TopConf LinzCode lifecycle in the jvm - TopConf Linz
Code lifecycle in the jvm - TopConf LinzIvan Krylov
 
2013.02.02 지앤선 테크니컬 세미나 - Xcode를 활용한 디버깅 팁(OSXDEV)
2013.02.02 지앤선 테크니컬 세미나 - Xcode를 활용한 디버깅 팁(OSXDEV)2013.02.02 지앤선 테크니컬 세미나 - Xcode를 활용한 디버깅 팁(OSXDEV)
2013.02.02 지앤선 테크니컬 세미나 - Xcode를 활용한 디버깅 팁(OSXDEV)JiandSon
 
Down the Rabbit Hole: An Adventure in JVM Wonderland
Down the Rabbit Hole: An Adventure in JVM WonderlandDown the Rabbit Hole: An Adventure in JVM Wonderland
Down the Rabbit Hole: An Adventure in JVM WonderlandCharles Nutter
 
Asynchronous single page applications without a line of HTML or Javascript, o...
Asynchronous single page applications without a line of HTML or Javascript, o...Asynchronous single page applications without a line of HTML or Javascript, o...
Asynchronous single page applications without a line of HTML or Javascript, o...Robert Schadek
 
Fast as C: How to Write Really Terrible Java
Fast as C: How to Write Really Terrible JavaFast as C: How to Write Really Terrible Java
Fast as C: How to Write Really Terrible JavaCharles Nutter
 
Ruby Performance - The Last Mile - RubyConf India 2016
Ruby Performance - The Last Mile - RubyConf India 2016Ruby Performance - The Last Mile - RubyConf India 2016
Ruby Performance - The Last Mile - RubyConf India 2016Charles Nutter
 
JavaOne 2011 - JVM Bytecode for Dummies
JavaOne 2011 - JVM Bytecode for DummiesJavaOne 2011 - JVM Bytecode for Dummies
JavaOne 2011 - JVM Bytecode for DummiesCharles Nutter
 
Implementing a JavaScript Engine
Implementing a JavaScript EngineImplementing a JavaScript Engine
Implementing a JavaScript EngineKris Mok
 
Javascript Everywhere
Javascript EverywhereJavascript Everywhere
Javascript EverywherePascal Rettig
 
ooc - OSDC 2010 - Amos Wenger
ooc - OSDC 2010 - Amos Wengerooc - OSDC 2010 - Amos Wenger
ooc - OSDC 2010 - Amos WengerAmos Wenger
 
node.js and native code extensions by example
node.js and native code extensions by examplenode.js and native code extensions by example
node.js and native code extensions by examplePhilipp Fehre
 
A deep dive into PEP-3156 and the new asyncio module
A deep dive into PEP-3156 and the new asyncio moduleA deep dive into PEP-3156 and the new asyncio module
A deep dive into PEP-3156 and the new asyncio moduleSaúl Ibarra Corretgé
 

What's hot (20)

Øredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...
Øredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...Øredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...
Øredev 2011 - JVM JIT for Dummies (What the JVM Does With Your Bytecode When ...
 
Understanding Javascript Engines
Understanding Javascript Engines Understanding Javascript Engines
Understanding Javascript Engines
 
Node.js/io.js Native C++ Addons
Node.js/io.js Native C++ AddonsNode.js/io.js Native C++ Addons
Node.js/io.js Native C++ Addons
 
Virtual machine and javascript engine
Virtual machine and javascript engineVirtual machine and javascript engine
Virtual machine and javascript engine
 
What to expect from Java 9
What to expect from Java 9What to expect from Java 9
What to expect from Java 9
 
Unleash your inner console cowboy
Unleash your inner console cowboyUnleash your inner console cowboy
Unleash your inner console cowboy
 
Code lifecycle in the jvm - TopConf Linz
Code lifecycle in the jvm - TopConf LinzCode lifecycle in the jvm - TopConf Linz
Code lifecycle in the jvm - TopConf Linz
 
2013.02.02 지앤선 테크니컬 세미나 - Xcode를 활용한 디버깅 팁(OSXDEV)
2013.02.02 지앤선 테크니컬 세미나 - Xcode를 활용한 디버깅 팁(OSXDEV)2013.02.02 지앤선 테크니컬 세미나 - Xcode를 활용한 디버깅 팁(OSXDEV)
2013.02.02 지앤선 테크니컬 세미나 - Xcode를 활용한 디버깅 팁(OSXDEV)
 
Down the Rabbit Hole
Down the Rabbit HoleDown the Rabbit Hole
Down the Rabbit Hole
 
Down the Rabbit Hole: An Adventure in JVM Wonderland
Down the Rabbit Hole: An Adventure in JVM WonderlandDown the Rabbit Hole: An Adventure in JVM Wonderland
Down the Rabbit Hole: An Adventure in JVM Wonderland
 
Asynchronous single page applications without a line of HTML or Javascript, o...
Asynchronous single page applications without a line of HTML or Javascript, o...Asynchronous single page applications without a line of HTML or Javascript, o...
Asynchronous single page applications without a line of HTML or Javascript, o...
 
Fast as C: How to Write Really Terrible Java
Fast as C: How to Write Really Terrible JavaFast as C: How to Write Really Terrible Java
Fast as C: How to Write Really Terrible Java
 
Return of c++
Return of c++Return of c++
Return of c++
 
Ruby Performance - The Last Mile - RubyConf India 2016
Ruby Performance - The Last Mile - RubyConf India 2016Ruby Performance - The Last Mile - RubyConf India 2016
Ruby Performance - The Last Mile - RubyConf India 2016
 
JavaOne 2011 - JVM Bytecode for Dummies
JavaOne 2011 - JVM Bytecode for DummiesJavaOne 2011 - JVM Bytecode for Dummies
JavaOne 2011 - JVM Bytecode for Dummies
 
Implementing a JavaScript Engine
Implementing a JavaScript EngineImplementing a JavaScript Engine
Implementing a JavaScript Engine
 
Javascript Everywhere
Javascript EverywhereJavascript Everywhere
Javascript Everywhere
 
ooc - OSDC 2010 - Amos Wenger
ooc - OSDC 2010 - Amos Wengerooc - OSDC 2010 - Amos Wenger
ooc - OSDC 2010 - Amos Wenger
 
node.js and native code extensions by example
node.js and native code extensions by examplenode.js and native code extensions by example
node.js and native code extensions by example
 
A deep dive into PEP-3156 and the new asyncio module
A deep dive into PEP-3156 and the new asyncio moduleA deep dive into PEP-3156 and the new asyncio module
A deep dive into PEP-3156 and the new asyncio module
 

Similar to Build High-Performance Android Apps with Native Code

C++ in kernel mode
C++ in kernel modeC++ in kernel mode
C++ in kernel modecorehard_by
 
Raffaele Rialdi
Raffaele RialdiRaffaele Rialdi
Raffaele RialdiCodeFest
 
introduction to node.js
introduction to node.jsintroduction to node.js
introduction to node.jsorkaplan
 
Cross Platform App Development with C++
Cross Platform App Development with C++Cross Platform App Development with C++
Cross Platform App Development with C++Joan Puig Sanz
 
C Programming Training in Ambala ! Batra Computer Centre
C Programming Training in Ambala ! Batra Computer CentreC Programming Training in Ambala ! Batra Computer Centre
C Programming Training in Ambala ! Batra Computer Centrejatin batra
 
2013 syscan360 yuki_chen_syscan360_exploit your java native vulnerabilities o...
2013 syscan360 yuki_chen_syscan360_exploit your java native vulnerabilities o...2013 syscan360 yuki_chen_syscan360_exploit your java native vulnerabilities o...
2013 syscan360 yuki_chen_syscan360_exploit your java native vulnerabilities o...chen yuki
 
MattsonTutorialSC14.pptx
MattsonTutorialSC14.pptxMattsonTutorialSC14.pptx
MattsonTutorialSC14.pptxgopikahari7
 
Gae icc fall2011
Gae icc fall2011Gae icc fall2011
Gae icc fall2011Juan Gomez
 
Exploiting GPU's for Columnar DataFrrames by Kiran Lonikar
Exploiting GPU's for Columnar DataFrrames by Kiran LonikarExploiting GPU's for Columnar DataFrrames by Kiran Lonikar
Exploiting GPU's for Columnar DataFrrames by Kiran LonikarSpark Summit
 
JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?Doug Hawkins
 
Nodejs - Should Ruby Developers Care?
Nodejs - Should Ruby Developers Care?Nodejs - Should Ruby Developers Care?
Nodejs - Should Ruby Developers Care?Felix Geisendörfer
 
Eclipse Day India 2015 - Java bytecode analysis and JIT
Eclipse Day India 2015 - Java bytecode analysis and JITEclipse Day India 2015 - Java bytecode analysis and JIT
Eclipse Day India 2015 - Java bytecode analysis and JITEclipse Day India
 
App secforum2014 andrivet-cplusplus11-metaprogramming_applied_to_software_obf...
App secforum2014 andrivet-cplusplus11-metaprogramming_applied_to_software_obf...App secforum2014 andrivet-cplusplus11-metaprogramming_applied_to_software_obf...
App secforum2014 andrivet-cplusplus11-metaprogramming_applied_to_software_obf...Cyber Security Alliance
 
Static code analysis: what? how? why?
Static code analysis: what? how? why?Static code analysis: what? how? why?
Static code analysis: what? how? why?Andrey Karpov
 

Similar to Build High-Performance Android Apps with Native Code (20)

Android ndk
Android ndkAndroid ndk
Android ndk
 
C++ in kernel mode
C++ in kernel modeC++ in kernel mode
C++ in kernel mode
 
DIY Java Profiling
DIY Java ProfilingDIY Java Profiling
DIY Java Profiling
 
Raffaele Rialdi
Raffaele RialdiRaffaele Rialdi
Raffaele Rialdi
 
introduction to node.js
introduction to node.jsintroduction to node.js
introduction to node.js
 
Cross Platform App Development with C++
Cross Platform App Development with C++Cross Platform App Development with C++
Cross Platform App Development with C++
 
C Programming Training in Ambala ! Batra Computer Centre
C Programming Training in Ambala ! Batra Computer CentreC Programming Training in Ambala ! Batra Computer Centre
C Programming Training in Ambala ! Batra Computer Centre
 
2013 syscan360 yuki_chen_syscan360_exploit your java native vulnerabilities o...
2013 syscan360 yuki_chen_syscan360_exploit your java native vulnerabilities o...2013 syscan360 yuki_chen_syscan360_exploit your java native vulnerabilities o...
2013 syscan360 yuki_chen_syscan360_exploit your java native vulnerabilities o...
 
MattsonTutorialSC14.pdf
MattsonTutorialSC14.pdfMattsonTutorialSC14.pdf
MattsonTutorialSC14.pdf
 
Klee and angr
Klee and angrKlee and angr
Klee and angr
 
Valgrind
ValgrindValgrind
Valgrind
 
MattsonTutorialSC14.pptx
MattsonTutorialSC14.pptxMattsonTutorialSC14.pptx
MattsonTutorialSC14.pptx
 
Gae icc fall2011
Gae icc fall2011Gae icc fall2011
Gae icc fall2011
 
Exploiting GPU's for Columnar DataFrrames by Kiran Lonikar
Exploiting GPU's for Columnar DataFrrames by Kiran LonikarExploiting GPU's for Columnar DataFrrames by Kiran Lonikar
Exploiting GPU's for Columnar DataFrrames by Kiran Lonikar
 
JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?
 
Nodejs - Should Ruby Developers Care?
Nodejs - Should Ruby Developers Care?Nodejs - Should Ruby Developers Care?
Nodejs - Should Ruby Developers Care?
 
Eclipse Day India 2015 - Java bytecode analysis and JIT
Eclipse Day India 2015 - Java bytecode analysis and JITEclipse Day India 2015 - Java bytecode analysis and JIT
Eclipse Day India 2015 - Java bytecode analysis and JIT
 
App secforum2014 andrivet-cplusplus11-metaprogramming_applied_to_software_obf...
App secforum2014 andrivet-cplusplus11-metaprogramming_applied_to_software_obf...App secforum2014 andrivet-cplusplus11-metaprogramming_applied_to_software_obf...
App secforum2014 andrivet-cplusplus11-metaprogramming_applied_to_software_obf...
 
Static code analysis: what? how? why?
Static code analysis: what? how? why?Static code analysis: what? how? why?
Static code analysis: what? how? why?
 
C++ Advanced Features
C++ Advanced FeaturesC++ Advanced Features
C++ Advanced Features
 

More from Kenneth Geisshirt

Building parsers in JavaScript
Building parsers in JavaScriptBuilding parsers in JavaScript
Building parsers in JavaScriptKenneth Geisshirt
 
Building mobile apps with Realm for React Native
Building mobile apps with Realm for React NativeBuilding mobile apps with Realm for React Native
Building mobile apps with Realm for React NativeKenneth Geisshirt
 
Tales from the dark side: developing SDKs at scale
Tales from the dark side: developing SDKs at scaleTales from the dark side: developing SDKs at scale
Tales from the dark side: developing SDKs at scaleKenneth Geisshirt
 
Is the database a solved problem?
Is the database a solved problem?Is the database a solved problem?
Is the database a solved problem?Kenneth Geisshirt
 
Unleash your inner console cowboy
Unleash your inner console cowboyUnleash your inner console cowboy
Unleash your inner console cowboyKenneth Geisshirt
 
Unleash your inner console cowboy
Unleash your inner console cowboyUnleash your inner console cowboy
Unleash your inner console cowboyKenneth Geisshirt
 
Naturvidenskabsfestival 2012
Naturvidenskabsfestival 2012Naturvidenskabsfestival 2012
Naturvidenskabsfestival 2012Kenneth Geisshirt
 
Hadoop - the data scientist's toolbox
Hadoop - the data scientist's toolboxHadoop - the data scientist's toolbox
Hadoop - the data scientist's toolboxKenneth Geisshirt
 
JavaScript/Emacs integration
JavaScript/Emacs integrationJavaScript/Emacs integration
JavaScript/Emacs integrationKenneth Geisshirt
 
Introduction to JavaScript for Modern Software Development
Introduction to JavaScript for Modern Software DevelopmentIntroduction to JavaScript for Modern Software Development
Introduction to JavaScript for Modern Software DevelopmentKenneth Geisshirt
 

More from Kenneth Geisshirt (15)

Building parsers in JavaScript
Building parsers in JavaScriptBuilding parsers in JavaScript
Building parsers in JavaScript
 
Open Source in Real Life
Open Source in Real LifeOpen Source in Real Life
Open Source in Real Life
 
Building mobile apps with Realm for React Native
Building mobile apps with Realm for React NativeBuilding mobile apps with Realm for React Native
Building mobile apps with Realm for React Native
 
micro:bit and JavaScript
micro:bit and JavaScriptmicro:bit and JavaScript
micro:bit and JavaScript
 
Tales from the dark side: developing SDKs at scale
Tales from the dark side: developing SDKs at scaleTales from the dark side: developing SDKs at scale
Tales from the dark side: developing SDKs at scale
 
Android things
Android thingsAndroid things
Android things
 
Is the database a solved problem?
Is the database a solved problem?Is the database a solved problem?
Is the database a solved problem?
 
Unleash your inner console cowboy
Unleash your inner console cowboyUnleash your inner console cowboy
Unleash your inner console cowboy
 
Sociale netværk
Sociale netværkSociale netværk
Sociale netværk
 
Unleash your inner console cowboy
Unleash your inner console cowboyUnleash your inner console cowboy
Unleash your inner console cowboy
 
Naturvidenskabsfestival 2012
Naturvidenskabsfestival 2012Naturvidenskabsfestival 2012
Naturvidenskabsfestival 2012
 
Hadoop - the data scientist's toolbox
Hadoop - the data scientist's toolboxHadoop - the data scientist's toolbox
Hadoop - the data scientist's toolbox
 
JavaScript/Emacs integration
JavaScript/Emacs integrationJavaScript/Emacs integration
JavaScript/Emacs integration
 
Introduction to JavaScript for Modern Software Development
Introduction to JavaScript for Modern Software DevelopmentIntroduction to JavaScript for Modern Software Development
Introduction to JavaScript for Modern Software Development
 
Kendthed og vigtighed
Kendthed og vigtighedKendthed og vigtighed
Kendthed og vigtighed
 

Recently uploaded

Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)OPEN KNOWLEDGE GmbH
 
Engage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyEngage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyFrank van der Linden
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEOrtus Solutions, Corp
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfjoe51371421
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...ICS
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...OnePlan Solutions
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...soniya singh
 
Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - InfographicHr365.us smith
 
What is Binary Language? Computer Number Systems
What is Binary Language?  Computer Number SystemsWhat is Binary Language?  Computer Number Systems
What is Binary Language? Computer Number SystemsJheuzeDellosa
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 
Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)Intelisync
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...Christina Lin
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio, Inc.
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackVICTOR MAESTRE RAMIREZ
 
Project Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationProject Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationkaushalgiri8080
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 

Recently uploaded (20)

Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)
 
Engage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyEngage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The Ugly
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdf
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
 
Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - Infographic
 
What is Binary Language? Computer Number Systems
What is Binary Language?  Computer Number SystemsWhat is Binary Language?  Computer Number Systems
What is Binary Language? Computer Number Systems
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStack
 
Project Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationProject Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanation
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
Exploring iOS App Development: Simplifying the Process
Exploring iOS App Development: Simplifying the ProcessExploring iOS App Development: Simplifying the Process
Exploring iOS App Development: Simplifying the Process
 

Build High-Performance Android Apps with Native Code

  • 1. Tips and Tricks for Building High-Performance Android Apps using Native Code Kenneth Geisshirt kg@realm.io Realm Inc. @realm http://github.com/Realm/ http://realm.io/ JD Hancock: Reign of The Android. http://bit.ly/1GN8vmg
  • 2. Swen-Peter Ekkebus: Goal! http://bit.ly/1x1suYm Avinash Sharma: http://bit.ly/1aRorcH • Android development is not just Java • C and C++ can speed apps up - and reuse old legacy code • Learn a few tricks when working with Java Native Interface • Hands-on exercises Today’s Goal
  • 3. Agenda • Setting up your environment • Java Native Interface Exploratorium. After Dark: Time http://bit.ly/1aSQxo0 • Threading • Using non-NDK libraries1 • Benchmarking • Debugging 1NDK = Native Development Kit
  • 4. Advantages • Use C or C++ in your apps → no JIT needed as always machine instructions • Access to system calls (like mmap()) • Almost no limits on memory usage • OpenGL programming • Sharing code across platforms • Reusing legacy libraries Alan Bates. Good Times http://bit.ly/1BXX7FN
  • 5. Disadvantages • C and C++ memory management → easy to crash your app • And debugging across languages is hard • Bionic C library isn’t the GNU C library • Doing a native call is expensive (in time) • Cumbersome to use non-NDK libraries Rocher: That_Sux http://bit.ly/1BdGNhJ
  • 6. Use Cases • AndEngine (2D Game Engine) http://www.andengine.org • ImageMagick for Android https://github.com/paulasiimwe/Android-ImageMagick • LevelDB for Android https://github.com/litl/android-leveldb • Support Vector Machine for Android https://github.com/cnbuff410/Libsvm-androidjni See-ming Lee; Rainbow Teddy shows BBF Stitch how to use the Canon EOS M; http://bit.ly/1O3yA43
  • 8. Example: estimating π Estimating π using dart • Throw arrows at random • Nhit/N = A/4 (quarter of a circle) • A = π·r2 (area of a circle) • π = 4·Nhit/N (with r = 1) Bogdan Suditu: Darts. http://bit.ly/18jCExj for i = 1,..,N x = random(0, 1) y = random(0, 1) if (sqrt(x·x+y·y) < 1) Nhit = Nhit +1 π = 4·Nhit/N
  • 9. Example: the classes Random number generator • Constructor with seed • Method uniform() to return random number between 0.0 and 1.0 π estimator • Constructor with number of iteration • Method estimate() to calculate the value of π Quinn Dombrowski: Pi http://bit.ly/1Kz55cp jeramiah.andrick. My random number generator http://bit.ly/1wbTbP2
  • 10. • Implement two C++ classes 1. RNG - a random number generator • uniform() returns a number in [0, 1[ 2. pi - a π estimator using MC algorithm • estimate() returns π • Write simple test program • Compile using clang++ or g++ • Go to https://github.com/kneth/AndroidCalcPi if lazy 😄 • Branch: initial Exercise 1
  • 11. The environment • Android Studio 1.3.0 (July 28, 2015) • Java 1.8 JDK • or set version (▶ Build ▶ Build types) • Android SDK 24.3.3 • Android NDK can now be bundled • Gradle 2.5 • gradle-wrapper.properties • A rooted device is nice to have • Always use Intel HAXM for the emulator Dave Gingrich;http://bit.ly/1HxRJWj ndk.dir=/usr/local/Cellar/android-sdk/24.3.3/ndk-bundle sdk.dir=/usr/local/Cellar/android-sdk/23.0.2 local.properties
  • 14. Organize your files • Use the experimental Android plugin for Gradle • Place C/C++ files in app/src/main/jni/ • Add ndk.dir to local.properties • Add an ndk section to your app’s build.gradle android.ndk { moduleName = "calcPi" cppFlags += ["-fexceptions"] stl = "gnustl_shared" // for exceptions }
  • 15. Building and Loading your native code • Automatically build for all supported architectures (ARM, ARMv7, ARM64, MIPS, MIPS64, x86, x86-64) • Android only installs the relevant architecture • Load native code early (main activity’s onCreate) System.loadLibrary("calcPi"); The module name (from build.gradle) Thomas Hawk: Loading Zone http://bit.ly/1MoBk9S
  • 16. Calling a C++ function • Use Java’s native keyword in the signature • Implement the function in C++ • Use a long to store the C++ pointer when you creates an object lamont_cranston: call center http://bit.ly/1A4JlK5 native long nativeCreate(long iterations); native double nativeEstimate(long nativePtr); Tell the Java compiler it’s a native function Returns a pointer (a C++ object) Operates on a C++ object
  • 17. Generate header files • .class files contain information about native calls • javah can extract signatures and generate C/C++ header files Paul: Generator Room Door http://bit.ly/1C3SSs7 !/bin/bash # Setting up CLASSDIR="$(pwd)/../app/build/intermediates/classes/debug" JNIDIR="$(pwd)" # Generate the headers (cd "$CLASSDIR" && javah -jni -classpath "$CLASSDIR" -d "$JNIDIR" net.zigzak.androidcalcpi.NativePi net.zigzak.androidcalcpi.NativeRNG) # Remove "empty" header files (they have 13 lines) wc -l "$JNIDIR"/*.h | grep " 13 " | awk '{print $2}' | xargs rm -f Classes to extract from Add path to jar files you depend on
  • 18. Java types in C/C++ • Java types are mapped to C/C++ types • Convert Date to long before call • Pass pointers over as long/ jlong Java C/C++ long jlong String jstring long[] jlongArray Object jObject float jfloat JNIEXPORT jdouble JNICALL Java_net_zigzak_androidcalcpi_NativePi_nativeEstimate (JNIEnv *, jobject, jlong nativePtr) { Pi *pi = reinterpret_cast<Pi *>(nativePtr); double estimate = pi->estimate(); return estimate; } Generated function name cast to a proper C++ pointer The pointer Define as a macro if used often: #define P(x) reinterpret_cast<Pi *>(x)
  • 19. Working with arrays • Copy values from JVM memory to C/C ++ memory • Remember to free C/C++ memory → avoid memory leaks jsize arr_len = env->GetArrayLength(columnIndexes); jlong *arr = env->GetLongArrayElements(columnIndexes, NULL); // use the elements of arr env->ReleaseLongArrayElements(columnIndexes, arr, 0); • Create a new Java array • Copy C/C++ array to Java array jArray = env->NewByteArray(jlen); if (jArray) // Copy data to Byte[] env->SetByteArrayRegion(jArray, 0, jlen, reinterpret_cast<const jbyte*>(bufPtr)); free(bufPtr); return jArray;
  • 20. Strings as trouble-makers• Java strings are in modified UTF-8 • null character encoded as 0xC0 0x80 (not valid UTF-8) • Many C/C++ libraries assume plain UTF-8 jchar stack_buf[stack_buf_size]; // adding characters to stack_bf jchar* out_begin = stack_buf; if (int_cast_with_overflow_detect(out_curr - out_begin, out_size)) throw runtime_error("String size overflow"); return env->NewString(out_begin, out_size); jstring s; // typical a JNI function parameter jchar *c = e->GetStringChars(s, 0); // use c env->ReleaseStringChars(s, c); Create a new Java string • Copy Java string to C/C++ array • Remember to deallocate C array
  • 21. Exercise 2 • Create a simple Android app • Implement Java classes RNG and Pi • Generate header files • Implement intermediate C++ function and call original C++ code • Go to https://github.com/kneth/AndroidCalcPi if lazy 😄 • branch wrapping
  • 22. C++ exceptions • C++ code can throw exceptions • new can throw bad_alloc,etc. • If uncaught the app crashes with hard-to- understand messages in the log Build fingerprint: 'generic_x86/sdk_x86/generic_x86:4.4.2/KK/999428:eng/test-keys' Revision: '0' pid: 1890, tid: 1890, name: t.zigzak.calcpi >>> net.zigzak.calcpi <<< signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr -------- eax 00000000 ebx 00000762 ecx 00000762 edx 00000006 esi 00000762 edi 0000000b xcs 00000073 xds 0000007b xes 0000007b xfs 00000000 xss 0000007b eip b7707c96 ebp b776cce0 esp bfa22090 flags 00200203 backtrace: #00 pc 0003bc96 /system/lib/libc.so (tgkill+22) #01 pc 00000005 <unknown> stack: bfa22050 00000001 bfa22054 b899c6d0 [heap] bfa22058 00000015 bfa2205c b76d9ef9 /system/lib/libc.so (pthread_mutex_unlock+25) bfa22060 a73bfd19 /data/app-lib/net.zigzak.calcpi-1/libgnustl_shared.so bfa22064 b7767fcc /system/lib/libc.so • Better solution: • catch and rethrow as Java exception
  • 23. Throwing a Java exception • You don’t throw an exception • You set the “exception” state in the JVM • Return from C/C++ function try { Pi *pi = new Pi(static_cast<long>(iterations)); return reinterpret_cast<jlong>(pi); } catch (std::exception& e) { jclass jExceptionClass = env->FindClass("java/lang/RuntimeException"); std::ostringstream message; message << "Allocating native class Pi failed: " << e.what(); env->ThrowNew(jExceptionClass, message.str().c_str()); env->DeleteLocalRef(jExceptionClass); } return 0; " Get a reference to the exception # Set the “exception” state $ Clean up followtheinstructrions: hand werpen http://bit.ly/1Bo3gZx
  • 24. Logging • JNI provides access to the Android log • __android_log_print is a simple variadic log function • Linking with liblog is required • size_t depends on bit width → cast to int64_t before logging vitelone: Deck Log Book http://bit.ly/1AXKZ0j android.ndk { moduleName = "calcPi" cppFlags += ["-fexceptions"] ldLibs += ["log"] stl = "gnustl_shared" // for exceptions } Link flag #define LOG(...) __android_log_print(ANDROID_LOG_DEBUG, "calcPi", __VA_ARGS__); Macro to simplify logging
  • 25. Tracing JNI calls • It is useful the trace calls • Define ENTER, ENTER_PTR, and LEAVE macros • Logging native pointer as jlong often produce negative numbers - don’t worry 1955-1955/net.zigzak.calcpi D/calcPi﹕ Enter Java_net_zigzak_calcpi_NativePi_nativeCreate 1955-1955/net.zigzak.calcpi D/calcPi﹕ iterations: 10000 1955-1955/net.zigzak.calcpi D/calcPi﹕ Enter Java_net_zigzak_calcpi_NativePi_nativeEstimate -1202665872 1955-1955/net.zigzak.calcpi D/calcPi﹕ estimate = 3.128400e+00
  • 26. Exercise 3 • Catch common C++ exceptions (bad_alloc) • Rethrow as a Java exception • Adding logging/tracing of JNI calls • Go to https://github.com/kneth/AndroidCalcPi if lazy 😄 • branch exceptions-and-logging
  • 28. Reduce size • Compiler can optimise for size (-Os) • Link Time Optimizations (LTO) can reduce size of native code • Eliminate unused code (-ffunction-sections -fdata- sections) and unused ELF symbols (- fvisibility=hidden) android.ndk { moduleName = "calcPi" cppFlags += ["-Os", "-fexceptions", "-fvisibility=hidden" "-ffunction-sections", "-fdata-sections", "-Wl,--gc-sections", "-flto"] ldLibs += "log" stl = "gnustl_shared" // for exceptions ldFlags += ["-Wl,--gc-sections", "-flto"] // reduce size } http://realm.io/news/reducing-apk-size-native-libraries/
  • 30. POSIX threads • Android’s Bionic C library supports POSIX threads • except cancellation • Threading can utilize your device’s cores • If you utilize all cores for longer times, you get W/art﹕ Suspending all threads took: 40.036ms I/Choreographer﹕ Skipped 18858 frames! The application may be doing too much work on its main thread.
  • 31. Exercise 4 • Add a π estimator using POSIX threads • reuse the estimate method • Go to https://github.com/kneth/AndroidCalcPi if lazy 😄 • branch posix-threads
  • 33. Libraries • NDK has some libraries • Basic ones: standard C, logging, etc. • Linked during build • Android has many other libraries • /system/lib is their home • OpenSSL, XML2, SQLite, ICU
  • 34. How to use? • Android has dynamic linking • Add dl to ldFlags • Include dlfcn.h in your C/C++ files • You might have to declare relevant structs and types SHA256_CTX ctx; int (*SHA224_Init)(SHA256_CTX *); SHA224_Init = reinterpret_cast<int (*)(SHA256_CTX*)> (dlsym(RTLD_DEFAULT, “SHA224_Init”)); SHA224_Init(&ctx); Function pointer Find symbol in .so file
  • 35. Exercise 5 • Add method to a class • Load one or two libcrypto functions • and call them • Go to https://github.com/kneth/AndroidCalcPi if lazy 😄 • branch non-ndk-libraries
  • 37. What makes benchmarking hard? • Android devices do many things • checking for updates, synchronising accounts, garbage collection, etc. • Android timers are not reliable • Just-in-Time compilation William Warby, Triple Timer; http://bit.ly/1TwetP4
  • 38. Measuring timer resolution • Use Debug.threadCpuTimeNano s() • But resolution depends on device • Microbenchmark must be longer than resolution • Resolution is used to validate benchmark • Go to https://github.com/kneth/ AndroidCalcPi • branch benchmarking long diff = 50000; for (int i = 0; i < 100; i++) { long end; long start = Debug.threadCpuTimeNanos(); while (true) { end = Debug.threadCpuTimeNanos(); if (end != start) { if (diff > (end - start)) { diff = end - start; } break; } } }
  • 40. Android Debug Bridge • Android Debug Bridge (adb) has some useful subcommands • shell: plain command-line shell • pull: copy file from device • push: copy file to device M. O’Thompsonski, http://bit.ly/1Da0o0h
  • 41. Get stack trace • Android apps are processes • Dump stack traces using kill • Log every native call mkdir -p /data/anr ps # find your app kill -3 <pid> cat /data/anr/traces.txt #define ENTER_PTR(ptr) __android_log_print(ANDROID_LOG_DEBUG,"calcPi", "Enter %s %" PRId64, __FUNCTION__, static_cast<int64_t>(ptr)); Forces 64 bit value! The name of the function
  • 42. Checking native memory • The emulator can help checking malloc • C/C++ makes it easy to do memory management wrong • Set the debug level to 20 adb shell setprop libc.debug.malloc 20 adb shell stop adb shell start Steve Jurvetson, Primitive Memories; http://bit.ly/1HY80sf
  • 43. Native debugging • Android Studio 1.3 supports native debugging • gdb or lldb • Add a run configuration (native) android.buildTypes { debug { isJniDebuggable = true isDebuggable = true } } App’s build.grade
  • 44. References • High Performance Android Apps by Doug Sillars. O’Reilly Media, 2015. • Essential JNI by Rob Gordon. Prentice Hall, 1998. • The Java Native Interface by Sheng Liang. Addison-Wesley, 1999. • Android NDK by Sylvian Rataboil. Packt Publishing, 2012.