Native development kit (ndk) introduction
Topics covered include •
o What is an NDK and Why NDK? •
o Java Native Interface (JNI) •
o Using NDK •
o NDK and JNI by Example •
o NDK's Stable APIs
• Android NDK Multithreading
o Introduction To NDK Native Threading
o Creating and terminating native threads at Android NDK
Build with pthreads
Thread creation
Thread termination
o Synchronizing native threads with conditional variables at Android NDK
Initialize and destroy conditional variables
o Synchronizing native threads with semaphore at Android NDK
Initialize and destroy a semaphore
o Managing data for native threads at Android NDK
Using Native Development Toolkit . Information collected from many sources http://lyaug.fr/slides/presentation-ndk/#/step-11
http://psrdotcom.blogspot.fr/2011/12/android-ndk-jni-windows-xp7-with-3264.html
The Android Native Development Kit (NDK)
NDK Info
What , Why , Why not ?
Requirement Tools & Installation of NDK
Developing an ADD application that uses the NDK
Overview of Android NDK (Native Development Toolkit).
Android application development is primarily done with the Android SDK.
Apps are written in Java thus benefitting from the high-level constructs
of the managed environment as well as the wealth of functionality provided
by the Android application platform.
However, sometimes it is necessary to implement certain functionality natively
in C++, e.g. when access to hardware is required or 3rd party stacks have to
be included that are only available as C++ code.
The NDK is a lightweight development toolkit for writing native applications
and libraries that can interwork with Java application code.
The Android NDK is a set of tools that allows the integration of native code (C/C++) in your Android app. In this presentation get know interesting usages of NDK, advantages and disadvantages, and how to stat using it with Android Studio.
Using Native Development Toolkit . Information collected from many sources http://lyaug.fr/slides/presentation-ndk/#/step-11
http://psrdotcom.blogspot.fr/2011/12/android-ndk-jni-windows-xp7-with-3264.html
The Android Native Development Kit (NDK)
NDK Info
What , Why , Why not ?
Requirement Tools & Installation of NDK
Developing an ADD application that uses the NDK
Overview of Android NDK (Native Development Toolkit).
Android application development is primarily done with the Android SDK.
Apps are written in Java thus benefitting from the high-level constructs
of the managed environment as well as the wealth of functionality provided
by the Android application platform.
However, sometimes it is necessary to implement certain functionality natively
in C++, e.g. when access to hardware is required or 3rd party stacks have to
be included that are only available as C++ code.
The NDK is a lightweight development toolkit for writing native applications
and libraries that can interwork with Java application code.
The Android NDK is a set of tools that allows the integration of native code (C/C++) in your Android app. In this presentation get know interesting usages of NDK, advantages and disadvantages, and how to stat using it with Android Studio.
Using the Android Native Development Kit (NDK)DroidConTLV
Android NDK is used to integrate C/C++ code into Android applications. Learn when and how to use it ; and what it implies to do so from development, integration within Eclipse and Android Studio, to distribution.
http://fr.droidcon.com/2014/agenda/
http://fr.droidcon.com/2014/agenda/detail?title=The+Android+Native+Development+Kit
The Android NDK is used to integrate C/C++ code into Android applications and libraries.
Learn how you can use the NDK and NDK-based libraries with Eclipse and Android Studio, and how you can debug and optimize your code.
Discover what changes from the new Android Runtime may break your integration, and how you can target new 64-bit architectures with the upcoming android L-release.
Speaker : Alexander Weggerle, Intel
This meetup discussed different concepts for building Android applications for multiple versions and devices out on the market today. This included the ability to take advantage of new 2.0 and 2.1 features while still supporting 1.x users in the same binary.
How to implement a simple dalvik virtual machineChun-Yu Wang
This slide is an introduction to Android Dalvik Virtual Machine on a short course.
We use two hand-made JVM and DVM which called Simple JVM and Simple DVM respectively, to tell student how they work. A Foo Class was provided as a target for verifying the execution results of those VM. We hope it will help student to understand JVM and DVM quickly.
O Android NDK é a ferramenta que permite a utilização de código nativo (C/C++) em sua aplicação Android. Nesta apresentação conheça alguns usos interessantes do NDK, as vantagens e desvantagens de utilizá-lo, além de como começar a usar esta ferramenta com o Android Studio.
Android applications are an interesting target for
reverse engineering. They are written in Java, which is tradi-
tionally good to decompile and are executed by Google’s custom
Java virtual machine, making them interesting to study. In this
paper we present the basic methods and approaches as well as
the necessary tools to reverse engineer Android applications. We
discuss how to change Android applications and show alternative
approaches including man-in-the-middle attacks and automation.
With growth in app market it is essential to guard our android apps against possible threats, in this presentation we will walk through various tools and techniques which some one can use to reverse engineer an android app, we will see how some one can get access to APP DB, CODE, API, PREFERENCES.
We will also see different tools and techniques to guard our app against possible threats from code obfuscation with tools like dexgaurd to newer methods like verification of api calls using google play services.
This session was taken in Barcamp 13 bangalore http://barcampbangalore.org/bcb/bcb13/reverse-engineering-an-android-app-securing-your-android-apps-against-attacks
and bangalore android user group meetup Jan meetup http://www.meetup.com/blrdroid/events/100360682/
Join Jim McKeeth as he introduces you to FMXLinux, and shows how you can bring the power of FireMonkey to Linux.
Outline:
Installation via GetIt Package Manager
Linux, PAServer, SDK, & Package Installation
FMXLinux usage and Samples
FireDAC Database Access on Linux
Migrating from Windows VCL to FMXLinux
3rd Party FMXLinux Support
Deploying rich web apps via Broadway
https://embt.co/FMXLinuxIntro
Accelerate your software development with DockerAndrey Hristov
Docker is in all the news and this talk presents you the technology and shows you how to leverage it to build your applications according to the 12 factor application model.
Docker is in all the news and this talk presents you the technology and shows you how to leverage it to build your applications according to the 12 factor application model.
(COSCUP 2015) A Beginner's Journey to Mozilla SpiderMonkey JS EngineZongXian Shen
This is my slides of COSCUP 2015 at Taipei, Taiwan.
The material is about the engine implementation overview from a 3 month experienced mentor bug contributor.
It's 2021 and containerization has been happening for 7 years already.
In the Java space, there are several ways to package a Java application as a Docker image.
Let's discover them from the Dockerfile to the CNCF Buildpacks, mentioning the Jib way too!
Using the Android Native Development Kit (NDK)DroidConTLV
Android NDK is used to integrate C/C++ code into Android applications. Learn when and how to use it ; and what it implies to do so from development, integration within Eclipse and Android Studio, to distribution.
http://fr.droidcon.com/2014/agenda/
http://fr.droidcon.com/2014/agenda/detail?title=The+Android+Native+Development+Kit
The Android NDK is used to integrate C/C++ code into Android applications and libraries.
Learn how you can use the NDK and NDK-based libraries with Eclipse and Android Studio, and how you can debug and optimize your code.
Discover what changes from the new Android Runtime may break your integration, and how you can target new 64-bit architectures with the upcoming android L-release.
Speaker : Alexander Weggerle, Intel
This meetup discussed different concepts for building Android applications for multiple versions and devices out on the market today. This included the ability to take advantage of new 2.0 and 2.1 features while still supporting 1.x users in the same binary.
How to implement a simple dalvik virtual machineChun-Yu Wang
This slide is an introduction to Android Dalvik Virtual Machine on a short course.
We use two hand-made JVM and DVM which called Simple JVM and Simple DVM respectively, to tell student how they work. A Foo Class was provided as a target for verifying the execution results of those VM. We hope it will help student to understand JVM and DVM quickly.
O Android NDK é a ferramenta que permite a utilização de código nativo (C/C++) em sua aplicação Android. Nesta apresentação conheça alguns usos interessantes do NDK, as vantagens e desvantagens de utilizá-lo, além de como começar a usar esta ferramenta com o Android Studio.
Android applications are an interesting target for
reverse engineering. They are written in Java, which is tradi-
tionally good to decompile and are executed by Google’s custom
Java virtual machine, making them interesting to study. In this
paper we present the basic methods and approaches as well as
the necessary tools to reverse engineer Android applications. We
discuss how to change Android applications and show alternative
approaches including man-in-the-middle attacks and automation.
With growth in app market it is essential to guard our android apps against possible threats, in this presentation we will walk through various tools and techniques which some one can use to reverse engineer an android app, we will see how some one can get access to APP DB, CODE, API, PREFERENCES.
We will also see different tools and techniques to guard our app against possible threats from code obfuscation with tools like dexgaurd to newer methods like verification of api calls using google play services.
This session was taken in Barcamp 13 bangalore http://barcampbangalore.org/bcb/bcb13/reverse-engineering-an-android-app-securing-your-android-apps-against-attacks
and bangalore android user group meetup Jan meetup http://www.meetup.com/blrdroid/events/100360682/
Join Jim McKeeth as he introduces you to FMXLinux, and shows how you can bring the power of FireMonkey to Linux.
Outline:
Installation via GetIt Package Manager
Linux, PAServer, SDK, & Package Installation
FMXLinux usage and Samples
FireDAC Database Access on Linux
Migrating from Windows VCL to FMXLinux
3rd Party FMXLinux Support
Deploying rich web apps via Broadway
https://embt.co/FMXLinuxIntro
Accelerate your software development with DockerAndrey Hristov
Docker is in all the news and this talk presents you the technology and shows you how to leverage it to build your applications according to the 12 factor application model.
Docker is in all the news and this talk presents you the technology and shows you how to leverage it to build your applications according to the 12 factor application model.
(COSCUP 2015) A Beginner's Journey to Mozilla SpiderMonkey JS EngineZongXian Shen
This is my slides of COSCUP 2015 at Taipei, Taiwan.
The material is about the engine implementation overview from a 3 month experienced mentor bug contributor.
It's 2021 and containerization has been happening for 7 years already.
In the Java space, there are several ways to package a Java application as a Docker image.
Let's discover them from the Dockerfile to the CNCF Buildpacks, mentioning the Jib way too!
Yocto Project Dev Day Prague 2017 - Advanced class - Kernel modules with eSDKMarco Cavallini
Excerpt of the lectures at Yocto Project Dev Day in Prague, 2017
During the advanced class Marco Cavallini ran this presentation about the creation of a Linux kernel module with eSDK.
NCDevCon 2017 - Cross Platform Mobile AppsJohn M. Wargo
Building cross-platform mobile apps using open source tools. A manic paced session where I build the same app across 4 different open source mobile development frameworks.
Mistakes to avoid when designing DLLs and thoughts about other platforms to deliever with your DLL.
Some compilers provide mechanisms to automatically export all functions and variables in a library that have external linkage. Avoid using any such mechanisms. Export exactly the interface that you need to export, and no more.
IBM Index 2018 Conference Workshop: Modernizing Traditional Java App's with D...Eric Smalling
Slides from my 2.5 hour hands-on workshop covering Docker basics, the Docker MTA program and how it applies to legacy Java applications and some tips on running those apps in containers in production.
One of the most important factor for failure or delaying in Project deliverable is Project Manager and not having clear picture and agenda by manager.
So, question is being a good project manager, make sure that deliverable's on time, what are the key points project manager should follow.
What is mobile wallet
MW is a solution for commercial transaction across domain and geography. Such as Osaifu Keitai, Smart Wallet, Softcard, Google Wallet, Passbook, MasterPass etc. Lots of solutions is available in market but still mobile wallets are n an early stage of market.
If we defined Mobile Wallet in One line, it is equivalent to the physical wallet (wallet in pocket) and which can be used for purchasing goods, cloths, services at any time and any location. It can be in form of ID or social security card, health card, payment card, tickets for transport, or movies or events, hotel bill, gift and coupons.
Mobile applications testing (challenges, tools & techniques)Rakesh Jha
Device Fragmentation is a Big Challenge
Devices Vary in Screen Size, Memory, Processing Power, Hardware Features etc.
Apple iPhone is Least Fragmented among All Mobile Platforms
Testing on All Target Handset/Devices
Almost Impractical if Number of Target Handsets is Large
Testing on All Target Operator Networks
Almost Impractical if Number of Target Operators is Large
Network Operator may Impose Certain Constraints
Introduction
Mobile Trends
Mobile Evolution
Top Ten Trends
Mobile Ecosystem
Smartphone Trends
Mobile Application Testing
Application Option
Approach to QA
Challenges
Implementation
Introduction to PhoneGap
Background
Setting up the environment for Android
Handling Events
Working With The Device, The Network, And Notifications
Getting Information from the Device
Determining the Connection Type
Using Notifications
Using Alerts
Using Confirmation Dialogs
Using Beeps
Using Vibrations
Accelerometer
Using the Acceleration Object
Using Accelerometer Methods
Media
The Media Object
Using Media Methods
Camera
Using The Camera Object
Using The Getpicture Method
Using Camera Options
Geolocation
Position, PositionError, Coord
Geolocation Methods
Geolocation Options
Deployment using Phonegap (Android)
Hands-on exercises
Storage
Available options
Db object
localStorage
Files
Filessystem
File read & write
Handling errors
Contacts
Creating contacts
Finding contacts
Handling errors
Capture
Video
Audio
Handling errors
Hands-on exercises
Introduction to PhoneGap
Background
Setting up the environment for Android
Handling Events
Working With The Device, The Network, And Notifications
Getting Information from the Device
Determining the Connection Type
Using Notifications
Using Alerts
Using Confirmation Dialogs
Using Beeps
Using Vibrations
Accelerometer
Using the Acceleration Object
Using Accelerometer Methods
Media
The Media Object
Using Media Methods
Camera
Using The Camera Object
Using The Getpicture Method
Using Camera Options
Geolocation
Position, PositionError, Coord
Geolocation Methods
Geolocation Options
Deployment using Phonegap (Android)
Hands-on exercises
Storage
Available options
Db object
localStorage
Files
Filessystem
File read & write
Handling errors
Contacts
Creating contacts
Finding contacts
Handling errors
Capture
Video
Audio
Handling errors
Hands-on exercises
Advanced JQuery Mobile tutorial with Phonegap Rakesh Jha
Introduction to jQuery Mobile (jQM) - cont'd
Getting started with jQM
-Downloading the Most Recent Version of jQuery Mobile
-Proper Markup for Loading Framework JavaScript and CSS
jQuery Mobile Page Structure
-Page Anatomy: Header, Footer and Content Sections
-Header and Footer Toolbars
-Bundling Pages into a Single Document
-Navigating Between Pages
Applying Different Theme Swatches
Page Initialization Events
jQuery Mobile Page Components
Basic Content Formatting
List Views
-Ordered and Unordered Lists
-Inset Lists
-Lists with Links
-Nested Lists
-Lists with Icons or Thumbnail Images
-Split Button Lists
-List Dividers
-Search Filters
Form Controls - check boxes, slider, etc.
Dialogs
Buttons and Toolbars
-Ways to Make a Button
-Placing Icons on Your Buttons
-Inline Buttons
-Button Groupings
-Navigation Toolbars
Collapsible Content
Event Handling
-Responding to various events
-Page related events
Ajax & Interaction with server (REST & SOAP)
Deployment using Phonegap (e.g. Android)
Overview of Android Devt Environment
Best Practices in jQM
Hands-on exercises
Introduction to CSS3
Text Formatting
Selectors
Box Model
Links, Backgrounds
Lists, Tables
Positioning & Layout
New features of CSS3 - transition, tranform, etc.
Introduction to jQueryMobile
Hands-on exercises
Introduction to jquery mobile with PhonegapRakesh Jha
Introduction to jQuery Mobile (jQM) - cont'd
Getting started with jQM
-Downloading the Most Recent Version of jQuery Mobile
-Proper Markup for Loading Framework JavaScript and CSS
jQuery Mobile Page Structure
-Page Anatomy: Header, Footer and Content Sections
-Header and Footer Toolbars
-Bundling Pages into a Single Document
-Navigating Between Pages
Applying Different Theme Swatches
Page Initialization Events
jQuery Mobile Page Components
Basic Content Formatting
List Views
-Ordered and Unordered Lists
-Inset Lists
-Lists with Links
-Nested Lists
-Lists with Icons or Thumbnail Images
-Split Button Lists
-List Dividers
-Search Filters
Form Controls - check boxes, slider, etc.
HTML5 Home
HTML5 Forms
HTML5 Reference
HTML5 Tags
HTML5 Canvas
Audio And Video
HTML5 new features
New Elements
New Attributes
Full CSS3 Support
Video and Audio
2D/3D Graphics
Local Storage
Local SQL Database
Web Applications
Multithreading and concurrency in androidRakesh Jha
Here you will learn -
What is Multithreading
What is concurrency
Process Vs Thread
Improvements and issues with concurrency
Limits of concurrency gains
Concurrency issues
Threads pools with the Executor Framework
AsyncTask and the UI Thread
Code
Android installation & configuration, and create HelloWorld Project
Native development kit (ndk) introduction
1. Native Development Kit (NDK) :
Introduction
Rakesh Kumar Jha
M. Tech, MBA
Delivery Manager
2. Contents
What is an NDK and Why NDK? ·
Java Native Interface (JNI) ·
Using NDK ·
NDK and JNI by Example ·
NDK's Stable APIs
Android NDK Multithreading
4. What is an NDK
• The NDK (Native Development Kit) is a tool
that allows you to program in C/C++ for
Android devices.
• It's intended to integrate with the SDK (it's
described as a "companion tool") and used
only for performance-critical portions of a
project.
5. Why NDK ?
• The NDK (Native Development Kit) allows you
to write code with C/C++ languages and then
call it from your Java application using JNI
(Java Native Interface)
6. Why NDK ?
• Using native code in java is reasonable
especially when you are dealing with
bits/bytes operations, like bitmaps
compression/decompression.
7. Why NDK ?
• NDK will not be interpreted like Java through
the JVM, instead it will use the operating
system API (in Android case, Linux) for those
operations, and thus its performance will be
much faster.
8. Why NDK ?
• One of the big advantages of the NDK is that
you can call custom allocation of memory
using malloc() method.
• However in the native code there is no GC
(Garbage collection), hence you need to free
memory by yourself.
9. Why NDK ?
• Potentially, you can increase your application
performance but sometime it can be just
overkill, so use it appropriately.
11. General steps for Java-NDK integration
1. Declare native method in java class.
2. Create a header file according to native
implementation.
3. Implement the header file on the native side
in C/C++ class.
4. Create an Android.mk file.
5. Compile native code to .so package/s.
6. Call the java native declaration method.
12. Step 1: Declare native method in java
class
1. First thing that we need to do is to create a
native method declaration in our Android
application class.
public class NDK_Methods
{
public static native String SayHello();
}
13. Step 2: Creating header file
What is Javah?
• Javah is a java utility that produces C headers
files from Java class, in order to provide an
interface through which Java and C code can
interact.
14. Step 2: Creating header file
Creating a Header file using javah utility
• After we created our native SayHello() method
declaration, we need to create a header file
which will be implemented in C class on the
native side.
• Steps:
– Go to the root directory of your project.
– Open a CMD.
– Type in"
15. Step 2: Creating header file
• javah -classpath bin/classes/ -d
jni/ndk.NDK_Methods
• -classpath bin/classes/: location of the classes
directory in which the compiled java classes of
your android application are located.
• -d jni/ndk.NDK_Methods : is a fully qualified
name of the class from which the header class
will be generated.
16. Step 2: Creating header file
• The generated header file will be created
under the jni directory in our project.
17. Step 2: Creating header file
• In example we will get the following header file:
#include <jni.h>
/* Header for class ndk_NDK_Methods */
#ifndef _Included_ndk_NDK_Methods
#define _Included_ndk_NDK_Methods
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: ndk_NDK_Methods
* Method: SayHelo
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_ndk_NDK_1Methods_SayHelo(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
18. Step 2: Creating header file
• Our java method declaration :
public static native String SayHello();
• Was generated to:
JNIEXPORT jstring JNICALL Java_ndk_NDK_1Methods_SayHelo (JNIEnv *, jclass);
• Notice that the generated name is Java
followed by package name, class and the
method separated by underscores.
•
19. Step 2: Creating header file
Since we did not pass any parameters to the
function we accept only the default parameters:
JNIEnv – is a pointer through which we are
communicating with java from the native
implementation.
jclass – a class that called the function.
21. Step 3: Implementing the Header file
• Now we have a header file and we need to
define an implementation for our method.
• We need to create a new file with c or cpp
extention in the jni directory and copy to it
the SayHello() method declaration:
22. Step 3: Implementing the Header file
//specifies the header file that is included
#include <ndk_NDK_Methods.h>
JNIEXPORT jstring JNICALL
Java_ndk_NDK_1Methods_SayHello(JNIEnv *env,
jobject thiz )
{
return (*env)->NewStringUTF(env, "Hello from
JNI!");
}
23. Step 3: Implementing the Header file
Notice that we are returning jstring which is
different from C string in our method.
We need to return a java object, so we are doing
it through the JniEnv pointer by calling
a NewStringUTF() method.
25. Step 4: Creating an Android.mk file
• In order to compile our file to .so package we
need to define an Android.mk file in our jni
directory.
• Android.mk file describes to the build system
about your sources.
• Android.mk contains those fields:
26. Step 4: Creating an Android.mk file
• LOCAL_PATH := $(call my-dir) - Android.mk must begin with this definition,
this defines the location of the sources. The macro ‘my-dir’ is the directory
of the Android.mk file.
• include$(CLEAR_VARS) – clears all variables that might be set from a
previous module build.
• LOCAL_MODULE :=native_lib – sets the name that is used as the identifier
for a module, which later used in java.
• LOCAL_SRC_FILES := native_lib – file that will be compiled in your module,
no need to specify headers, the system will take care of it.
• include $(BUILD_SHARED_LIBRARY) – ensures that shared library becomes
a part of this make.
27. Application.mk
• Not necessary for the compilation, but in our
case we specified:
• APP_ABI := all – sets the compilation for all
the supported CPUs.
• If we will not specify this, the compilation will
be made only for the default CPU. You can also
specify your CPU destination compilation
explicitly.
29. Step 5: Compiling the native code
What is ndk-build?
• An ndk-build is an NDK tool which is
responsible for compiling your native code to
executable files.
30. Compilation
• After we created the Android.mk file we can
create the .so package using ndk-build tool.
• Steps:
– Go to your root directory of the android application.
– Lunch the ndk-build utility with its full path, in my
case: C:/android_ndk/ndk-build.
• C:/android_ndk – The directory where you have
downloaded your NDK.
• ndk-build – The utility.
• This will create a .so package/s in libs directory in
our project.
32. Step 6: Calling native method
• What’s left for us to do, is to make a call from java
to JNI method in our application:
<a>
String ndkMessage = NDK_Methods.SayHelo();
</a>
• This will call the static method in NDK_Methods
class, that will call the
Java_ndk_NDK_1Methods_SayHelo() method
which is declared in the header file and
implemented in our C class
33. Java Native Interface (JNI)
• Install the JNI/NDK package from Google
• Create your Android project
• Make a JNI folder in your Android project root directory (called 'jni')
• Put your JNI sources in the 'jni' folder
• Create an 'Android.mk' file, and place it in the 'jni' folder
• Optionally create an 'Application.mk' file, and place it in the 'jni' folder
• Open a command line terminal and navigate to the root directory of your
Android project.
• Execute 'ndk-build', (if it's in your PATH variable) or execute
'/path/to/command/ndk-build'
• The 'ndk-build' command creates the binary for your library and puts it in
the proper folder.
• Switch to Eclipse, Refresh the 'Project Explorer View' (F5)
• Rebuild the project
• Run your project testing your JNI library.
34. Java Native Interface (JNI)
• Install the JNI/NDK package from Google
• Create your Android project
• Make a JNI folder in your Android project root directory (called 'jni')
• Put your JNI sources in the 'jni' folder
• Create an 'Android.mk' file, and place it in the 'jni' folder
• Optionally create an 'Application.mk' file, and place it in the 'jni' folder
• Open a command line terminal and navigate to the root directory of your
Android project.
• Execute 'ndk-build', (if it's in your PATH variable) or execute
'/path/to/command/ndk-build'
• The 'ndk-build' command creates the binary for your library and puts it in
the proper folder.
• Switch to Eclipse, Refresh the 'Project Explorer View' (F5)
• Rebuild the project
• Run your project testing your JNI library.
37. 1 - Stay on Target
• The newest devices are generally ARMv7,
meaning that it can pay to use v7 builds and
features. The latest version of the NDK adds
support ARMv7 and NEON code
38. 2 - Do not optimize immediately
• Unless you plan on porting an existing C++
application, do not rush into native.
39. 3 - Optimize like a ninja
• When you do optimize, sneak in, turn the key
bits of your application into super-fast native
or assembly code and get out cleanly.
• That way you should not compromise your
maintainability and ease of debugging.
40. 4. Re-factor around your
optimisations
• Once you have a design in place, do not be
afraid to re-arrange code to make more of it
suitable for optimising, but avoid tinkering too
much with native code once it is working.
• The Java code is more easily rearranged and
debugged.
41. 5 - Maintain a Java fall-back
• Executing unsupported native code is a bad idea;
at best it will
• cause your application to exit unexpectedly. It is
possible to determine with some confidence
whether or not your native code will be
compatible with the device the program is
running on, so as long as you have a Java
implementation available you can always fall back
to that.
• This is where the optimized Java version from tip
4 pays off extra.
42. 6 - Allocate with care
• Whenever possible allocate in Java anything
that is needed in Java rather than relying on
later, easily forgotten, calls to C to free.
• This minimises the chances of leaks and makes
the Java code simpler.
43. 7 - Multi-thread with great care
• With that in mind it is tempting to split
everything up into threads.
• It is a good idea in general, but remember
maxing out the load on your system may
speed up the result at the expense of the
second-to-second user experience. Even so,
used sensibly threads can be very effective
44. 8 - Thread at the Java Level
• When you do break your logic into threads, it
is better to do it via Java than pthreads
wherever possible.
• . There are fewer hazards and more language-level
tools for managing access with the Java
VM
45. 8 - Thread at the Java Level
• When you do break your logic into threads, it
is better to do it via Java than pthreads
wherever possible.
• . There are fewer hazards and more language-level
tools for managing access with the Java
VM
46. Creating and terminating native
threads at Android NDK
void jni_start_threads() {
pthread_t th1, th2;
int threadNum1 = 1, threadNum2 = 2;
int ret;
ret = pthread_create(&th1, NULL, run_by_thread, (void*)&threadNum1);
ret = pthread_create(&th2, NULL, run_by_thread, (void*)&threadNum2);
void *status;
ret = pthread_join(th1, &status);
int* st = (int*)status;
LOGI(1, "thread 1 end %d %d", ret, *st);
ret = pthread_join(th2, &status);
st = (int*)status;
LOGI(1, "thread 2 end %d %d", ret, *st);
}
47. Creating and terminating native
threads at Android NDK
int retStatus;
void *run_by_thread(void *arg) {
int cnt = 3, i;
int* threadNum = (int*)arg;
for (i = 0; i < cnt; ++i) {
sleep(1);
LOGI(1, "thread %d: %d", *threadNum, i);
}
if (1 == *threadNum) {
retStatus = 100;
return (void*)&retStatus;
} else if (2 == *threadNum) {
retStatus = 200;
pthread_exit((void*)&retStatus);
}
}
48. Creating and terminating native
threads at Android NDK
Add an Android.mk file in the jni folder with the
following code:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := NativeThreadsCreation
LOCAL_SRC_FILES := NativeThreadsCreation.cpp
LOCAL_LDLIBS := -llog
include $(BUILD_SHARED_LIBRARY)
49. Creating and terminating native
threads at Android NDK
Build and run the Android project, and use the
following command to monitor
the logcat output:
$ adb logcat -v time NativeThreadsCreation:I *:S
51. Synchronizing native threads with
mutex at Android NDK
1. Create an Android application
named NativeThreadsMutex.
2. Right-click on the
project NativeThreadsMutex, select Android
Tools | Add Native Support.
3. MainActivity Java file simply loads the
nativeNativeThreadsMutex library and calls
the native jni_start_threads method
52. Synchronizing native threads with
mutex at Android NDK
4. Add two file –
4. 1. mylog.h and
5. NativeThreadsMutex.cpp in
the jni folder.NativeThreadsMutex.cpp contains
the code to start two threads.
6. The two threads will update a shared counter.
53. Synchronizing native threads with
mutex at Android NDK
int cnt = 0;
int THR = 10;
void *run_by_thread1(void *arg) {
int* threadNum = (int*)arg;
while (cnt < THR) {
pthread_mutex_lock(&mux1);
while ( pthread_mutex_trylock(&mux2) ) {
pthread_mutex_unlock(&mux1); //avoid deadlock
usleep(50000); //if failed to get mux2, release mux1 first
pthread_mutex_lock(&mux1);
}
++cnt;
LOGI(1, "thread %d: cnt = %d", *threadNum, cnt);
pthread_mutex_unlock(&mux1);
pthread_mutex_unlock(&mux2);
sleep(1);
}
}
54. Synchronizing native threads with
mutex at Android NDK
void *run_by_thread2(void *arg) {
int* threadNum = (int*)arg;
while (cnt < THR) {
pthread_mutex_lock(&mux2);
while ( pthread_mutex_trylock(&mux1) ) {
pthread_mutex_unlock(&mux2); //avoid deadlock
usleep(50000); //if failed to get mux2, release mux1 first
pthread_mutex_lock(&mux2);
}
++cnt;
LOGI(1, "thread %d: cnt = %d", *threadNum, cnt);
pthread_mutex_unlock(&mux2);
pthread_mutex_unlock(&mux1);
sleep(1);
}
}
55. Synchronizing native threads with
mutex at Android NDK
Add an Android.mk file in the jni folder with the
following content:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := NativeThreadsMutex
LOCAL_SRC_FILES := NativeThreadsMutex.cpp
LOCAL_LDLIBS := -llog
include $(BUILD_SHARED_LIBRARY)
56. Synchronizing native threads with
mutex at Android NDK
Build and run the Android project, and use the
following command to monitor the logcat output
$ adb logcat -v time NativeThreadsMutex:I *:S
57. Synchronizing native threads with
conditional variables at Android NDK
Create an Android project that demonstrates the usage
of pthread conditional variables:
1. Create an Android application
named NativeThreadsCondVar.
2. Right-click on the project NativeThreadsCondVar,
select Android Tools | Add Native Support.
3. MainActivity.Java file simply loads the native
libraryNativeThreadsCondVar and calls the
native jni_start_threads method.
58. Synchronizing native threads with
conditional variables at Android NDK
4. Add two files under the jni folder –
4. mylog.h
5. NativeThreadsCondVar.cpp
5. NativeThreadsCondVar.cpp contains the code to
start two threads
6. The two threads will update a shared counter.
7. The jni_start_threads function initializes the
mutex, conditional variable and creates two
threads:
59. Synchronizing native threads with
conditional variables at Android NDK
pthread_mutex_t mux;
pthread_cond_t cond;
void jni_start_threads() {
pthread_t th1, th2;
int threadNum1 = 1, threadNum2 = 2;
int ret;
pthread_mutex_init(&mux, NULL);
pthread_cond_init(&cond, NULL);
ret = pthread_create(&th1, NULL, run_by_thread1,
void*)&threadNum1);
LOGI(1, "thread 1 started");
ret = pthread_create(&th2, NULL, run_by_thread2,
void*)&threadNum2);
LOGI(1, "thread 2 started");
ret = pthread_join(th1, NULL);
LOGI(1, "thread 1 end %d", ret);
ret = pthread_join(th2, NULL);
LOGI(1, "thread 2 end %d", ret);
pthread_mutex_destroy(&mux);
pthread_cond_destroy(&cond);
}
60. Synchronizing native threads with
conditional variables at Android NDK
int cnt = 0;
int THR = 10, THR2 = 5;
void *run_by_thread1(void *arg) {
int* threadNum = (int*)arg;
pthread_mutex_lock(&mux);
while (cnt != THR2) {
LOGI(1, "thread %d: about to wait", *threadNum);
pthread_cond_wait(&cond, &mux);
}
++cnt;
LOGI(1, "thread %d: cnt = %d", *threadNum, cnt);
pthread_mutex_unlock(&mux);
}
62. Synchronizing native threads with
conditional variables at Android NDK
Add an Android.mk file under the jni folder with
the following content:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := NativeThreadsCondVar
LOCAL_SRC_FILES := NativeThreadsCondVar.cpp
LOCAL_LDLIBS := -llog
include $(BUILD_SHARED_LIBRARY)
63. Synchronizing native threads with
conditional variables at Android NDK
Build and run the Android project, and use the
following command to monitor the logcat output-
$ adb logcat -v time NativeThreadsCondVar:I *:S
64. Synchronizing native threads with
reader/writer locks at Android NDK
1. Create an Android application named
NativeThreadsRWLock.
2. Right-click on the project NativeThreadsRWLock,
select Android Tools | Add Native Support.
3. MainActivity Java file simply loads the native
libraryNativeThreadsRWLock and calls the native
method jni_start_threads.
4. Add two files
named mylog.h and NativeThreadsRWLock.cpp und
er the jni folder.
65. Synchronizing native threads with
reader/writer locks at Android NDK
5. jni_start_threads starts pNumOfReader reader
threads and pNumOfWriter writer threads:
66. Synchronizing native threads with
reader/writer locks at Android NDK
void jni_start_threads(JNIEnv *pEnv, jobject pObj, int pNumOfReader, int pNumOfWriter) {
pthread_t *ths;
int i, ret;
int *thNum;
ths = (pthread_t*)malloc(sizeof(pthread_t)*(pNumOfReader+pNumOfWriter));
thNum = (int*)malloc(sizeof(int)*(pNumOfReader+pNumOfWriter));
pthread_rwlock_init(&rwlock, NULL);
for (i = 0; i < pNumOfReader + pNumOfWriter; ++i) {
thNum[i] = i;
if (i < pNumOfReader) {
ret = pthread_create(&ths[i], NULL, run_by_read_thread, (void*)&(thNum[i]));
} else {
ret = pthread_create(&ths[i], NULL, run_by_write_thread, (void*)&(thNum[i]));
}
}
for (i = 0; i < pNumOfReader+pNumOfWriter; ++i) {
ret = pthread_join(ths[i], NULL);
}
pthread_rwlock_destroy(&rwlock);
free(thNum);
free(ths);
}
67. Synchronizing native threads with
reader/writer locks at Android NDK
void *run_by_read_thread(void *arg) {
int* threadNum = (int*)arg;
int ifRun = 1;
int accessTimes = 0;
int ifPrint = 1;
while (ifRun) {
if (!pthread_rwlock_rdlock(&rwlock)) {
if (100000*numOfWriter == sharedCnt) {
ifRun = 0;
}
if (0 <= sharedCnt && ifPrint) {
LOGI(1, "reader thread %d sharedCnt value before processing %dn", *threadNum, sharedCnt);
int j, k;//some dummy processing
for (j = 0; j < 100000; ++j) {
k = j*2;
k = sqrt(k);
}
ifPrint = 0;
LOGI(1, "reader thread %d sharedCnt value after processing %d %dn", *threadNum, sharedCnt, k);
}
if ((++accessTimes) == INT_MAX/5) {
accessTimes = 0;
LOGI(1, "reader thread %d still running: %dn", *threadNum, sharedCnt);
}
pthread_rwlock_unlock(&rwlock);
}
}
LOGI(1, "reader thread %d return %dn", *threadNum, sharedCnt);
return NULL;
}
68. Synchronizing native threads with
reader/writer locks at Android NDK
void *run_by_write_thread(void *arg) {
int cnt = 100000, i, j, k;
int* threadNum = (int*)arg;
for (i = 0; i < cnt; ++i) {
if (!pthread_rwlock_wrlock(&rwlock)) {
int lastShCnt = sharedCnt;
for (j = 0; j < 10; ++j) { //some dummy processing
k = j*2;
k = sqrt(k);
}
sharedCnt = lastShCnt + 1;
pthread_rwlock_unlock(&rwlock);
}
}
LOGI(1, "writer thread %d return %d %dn", *threadNum, sharedCnt, k);
return NULL;
}
69. Synchronizing native threads with
reader/writer locks at Android NDK
Add an Android.mk file under the jni folder with the following
content:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := NativeThreadsRWLock
LOCAL_SRC_FILES := NativeThreadsRWLock.cpp
LOCAL_LDLIBS := -llog
include $(BUILD_SHARED_LIBRARY)
70. Synchronizing native threads with
reader/writer locks at Android NDK
Build and run the Android project, and use the following
command to monitor the logcat output:
adb logcat -v time NativeThreadsRWLock:I *:S
71. Synchronizing native threads with
semaphore at Android NDK
1 Create an Android application named
NativeThreadsSemaphore.
2 Right-click on the project NativeThreadsSemaphore, select
Android Tools | Add Native Support
3 Activity Java file simply loads the native
library NativeThreadsSemaphore and calls the
native jni_start_threads method.
4 Add two files
named mylog.h and NativeThreadsSemaphore.cpp under
the jni folder.
72. Synchronizing native threads with
semaphore at Android NDK
5. jni_start_threads creates pNumOfConsumer number of
consumer threads, pNumOfProducer number of producer
threads, and numOfSlots number of slots
73. Synchronizing native threads with
semaphore at Android NDK
void jni_start_threads(JNIEnv *pEnv, jobject pObj, int pNumOfConsumer, int pNumOfProducer, int numOfSlots) {
pthread_t *ths;
int i, ret;
int *thNum;
pthread_mutex_init(&mux, NULL);
sem_init(&emptySem, 0, numOfSlots);
sem_init(&fullSem, 0, 0);
ths = (pthread_t*)malloc(sizeof(pthread_t)*(pNumOfConsumer+pNumOfProducer));
thNum = (int*)malloc(sizeof(int)*(pNumOfConsumer+pNumOfProducer));
for (i = 0; i < pNumOfConsumer + pNumOfProducer; ++i) {
thNum[i] = i;
if (i < pNumOfConsumer) {
ret = pthread_create(&ths[i], NULL,
un_by_consumer_thread, (void*)&(thNum[i]));
} else {
ret = pthread_create(&ths[i], NULL, run_by_producer_thread, (void*)&(thNum[i]));
}
}
for (i = 0; i < pNumOfConsumer+pNumOfProducer; ++i) {
ret = pthread_join(ths[i], NULL);
}
sem_destroy(&emptySem);
sem_destroy(&fullSem);
pthread_mutex_destroy(&mux);
free(thNum);
free(ths);
}
74. Synchronizing native threads with
semaphore at Android NDK
void *run_by_producer_thread(void *arg) {
int* threadNum = (int*)arg;
int i;
for (i = 0; i < 4; ++i) {
sem_wait(&emptySem);
pthread_mutex_lock(&mux);
++numOfItems;
pthread_mutex_unlock(&mux);
sem_post(&fullSem);
}
return NULL;
}
75. Synchronizing native threads with
semaphore at Android NDK
Add an Android.mk file under the jni folder with the following
content:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := NativeThreadsSemaphore
LOCAL_SRC_FILES := NativeThreadsSemaphore.cpp
LOCAL_LDLIBS := -llog
include $(BUILD_SHARED_LIBRARY)
78. Managing data for native threads at
Android NDK
There are several options when we want to preserve thread-wide
data across functions, including global variables,
argument passing, and thread-specific data key.
Here we will discusses all the three options with a focus on
thread-specific data key.
79. Managing data for native threads at
Android NDK
Create an Android application named NativeThreadsData.
Right-click on the project NativeThreadsData, select Android
Tools | Add Native Support.
This Java file simply loads the native library
NativeThreadsData and calls the native methods.
Add mylog.h and NativeThreadsData.cpp files under the jni
folder. The mylog.h contains the Android native logcat utility
functions, while the NativeThreadsData.cpp file contains the
native code to start multiple threads.
80. Managing data for native threads at
Android NDK
jni_start_threads starts n number of threads, where n is
specified by the variable pNumOfThreads:
81. Managing data for native threads at
Android NDK
void jni_start_threads(JNIEnv *pEnv, jobject pObj, int pNumOfThreads) {
pthread_t *ths;
int i, ret;
int *thNum;
ths = (pthread_t*)malloc(sizeof(pthread_t)*pNumOfThreads);
thNum = (int*)malloc(sizeof(int)*pNumOfThreads);
pthread_mutex_init(&mux, NULL);
pthread_key_create(&muxCntKey, free_muxCnt);
for (i = 0; i < pNumOfThreads; ++i) {
thNum[i] = i;
ret = pthread_create(&ths[i], NULL, run_by_thread, (void*)&(thNum[i]));
}
for (i = 0; i < pNumOfThreads; ++i) {
ret = pthread_join(ths[i], NULL);
}
pthread_key_delete(muxCntKey);
pthread_mutex_destroy(&mux);
free(thNum);
free(ths);
}
82. Managing data for native threads at
Android NDK
The thread_step_1 function is executed by threads. It gets the
data associated with the thread- specific key and uses it to
count the number of times the mutex is locked:
83. Managing data for native threads at
Android NDK
void thread_step_1() {
struct timeval st, cu;
long stt, cut;
int *muxCntData = (int*)pthread_getspecific(muxCntKey);
gettimeofday(&st, NULL);
stt = st.tv_sec*1000 + st.tv_usec/1000;
do {
pthread_mutex_lock(&mux);
(*muxCntData)++;
pthread_mutex_unlock(&mux);
gettimeofday(&st, NULL);
cut = st.tv_sec*1000 + st.tv_usec/1000;
} while (cut - stt < 10000);
}
84. Managing data for native threads at
Android NDK
The thread_step_2 function is executed by threads. It gets the
data associated with the thread-specific key and prints it out:
void thread_step_2(int thNum) {
int *muxCntData = (int*)pthread_getspecific(muxCntKey);
LOGI(1, "thread %d: mux usage count: %dn", thNum,
*muxCntData);
}
85. Managing data for native threads at
Android NDK
The run_by_thread function is executed by threads:
void *run_by_thread(void *arg) {
int* threadNum = (int*)arg;
int *muxCntData = (int*)malloc(sizeof(int));
*muxCntData = 0;
pthread_setspecific(muxCntKey, (void*)muxCntData);
thread_step_1();
thread_step_2(*threadNum);
return NULL;
}
86. Managing data for native threads at
Android NDK
Add an Android.mk file under the jni folder with the following
content:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := NativeThreadsData
LOCAL_SRC_FILES := NativeThreadsData.cpp
LOCAL_LDLIBS := -llog
include $(BUILD_SHARED_LIBRARY)
87. Managing data for native threads at
Android NDK
Build and run the Android project, and use the following
command to monitor the logcat output –
$ adb logcat -v time NativeThreadsData:I *:S
88. Ref
Books and related material –
Android Native Development Kit Cookbook
By - by Feipeng Liu
Publisher: Packt Publishing