SlideShare ist ein Scribd-Unternehmen logo
1 von 89
Native Development Kit (NDK) : 
Introduction 
Rakesh Kumar Jha 
M. Tech, MBA 
Delivery Manager
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
What is an NDK and Why NDK?
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.
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)
Why NDK ? 
• Using native code in java is reasonable 
especially when you are dealing with 
bits/bytes operations, like bitmaps 
compression/decompression.
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.
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.
Why NDK ? 
• Potentially, you can increase your application 
performance but sometime it can be just 
overkill, so use it appropriately.
Why NDK ?
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.
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(); 
}
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.
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"
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.
Step 2: Creating header file 
• The generated header file will be created 
under the jni directory in our project.
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
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. 
•
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.
Step 3: Implementing the Header file
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:
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!"); 
}
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.
Step 4: Creating an Android.mk file
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:
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.
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.
Step 5: Compiling the native code
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.
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.
Step 6: Calling native method
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
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.
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.
Android NDK Multithreading
10 Android NDK Tips
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
2 - Do not optimize immediately 
• Unless you plan on porting an existing C++ 
application, do not rush into native.
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.
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.
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.
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.
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
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
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
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); 
}
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); 
} 
}
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)
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
Creating and terminating native 
threads at Android NDK
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
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.
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); 
} 
}
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); 
} 
}
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)
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
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.
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:
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); 
}
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); 
}
Synchronizing native threads with 
conditional variables at Android NDK 
void *run_by_thread2(void *arg) { 
int* threadNum = (int*)arg; 
while (cnt < THR) { 
pthread_mutex_lock(&mux); 
if (cnt == THR2) { 
pthread_cond_signal(&cond); 
} else { 
++cnt; 
LOGI(1, "thread %d: cnt = %d", *threadNum, cnt); 
} 
pthread_mutex_unlock(&mux); 
sleep(1); 
} 
}
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)
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
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.
Synchronizing native threads with 
reader/writer locks at Android NDK 
5. jni_start_threads starts pNumOfReader reader 
threads and pNumOfWriter writer threads:
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); 
}
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; 
}
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; 
}
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)
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
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.
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
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); 
}
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; 
}
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)
Synchronizing native threads with 
semaphore at Android NDK 
$ adb logcat -v time NativeThreadsSemaphore:I *:S
Managing data for native threads at 
Android NDK
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.
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.
Managing data for native threads at 
Android NDK 
 jni_start_threads starts n number of threads, where n is 
specified by the variable pNumOfThreads:
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); 
}
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:
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); 
}
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); 
}
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; 
}
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)
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
Ref 
Books and related material – 
Android Native Development Kit Cookbook 
By - by Feipeng Liu 
Publisher: Packt Publishing
Questions ?

Weitere ähnliche Inhalte

Was ist angesagt?

Using the Android Native Development Kit (NDK)
Using the Android Native Development Kit (NDK)Using the Android Native Development Kit (NDK)
Using the Android Native Development Kit (NDK)DroidConTLV
 
Using the android ndk - DroidCon Paris 2014
Using the android ndk - DroidCon Paris 2014Using the android ndk - DroidCon Paris 2014
Using the android ndk - DroidCon Paris 2014Paris Android User Group
 
Android Developer Meetup
Android Developer MeetupAndroid Developer Meetup
Android Developer MeetupMedialets
 
Android ndk - Introduction
Android ndk  - IntroductionAndroid ndk  - Introduction
Android ndk - IntroductionRakesh Jha
 
How to implement a simple dalvik virtual machine
How to implement a simple dalvik virtual machineHow to implement a simple dalvik virtual machine
How to implement a simple dalvik virtual machineChun-Yu Wang
 
Toward dynamic analysis of obfuscated android malware
Toward dynamic analysis of obfuscated android malwareToward dynamic analysis of obfuscated android malware
Toward dynamic analysis of obfuscated android malwareZongXian Shen
 
Understanding the Dalvik bytecode with the Dedexer tool
Understanding the Dalvik bytecode with the Dedexer toolUnderstanding the Dalvik bytecode with the Dedexer tool
Understanding the Dalvik bytecode with the Dedexer toolGabor Paller
 
How to reverse engineer Android applications
How to reverse engineer Android applicationsHow to reverse engineer Android applications
How to reverse engineer Android applicationshubx
 
Reverse engineering android apps
Reverse engineering android appsReverse engineering android apps
Reverse engineering android appsPranay Airan
 
FMXLinux Introduction - Delphi's FireMonkey for Linux
FMXLinux Introduction - Delphi's FireMonkey for LinuxFMXLinux Introduction - Delphi's FireMonkey for Linux
FMXLinux Introduction - Delphi's FireMonkey for LinuxEmbarcadero Technologies
 
Accelerate your software development with Docker
Accelerate your software development with DockerAccelerate your software development with Docker
Accelerate your software development with DockerAndrey Hristov
 
Accelerate your development with Docker
Accelerate your development with DockerAccelerate your development with Docker
Accelerate your development with DockerAndrey Hristov
 
(COSCUP 2015) A Beginner's Journey to Mozilla SpiderMonkey JS Engine
(COSCUP 2015) A Beginner's Journey to Mozilla SpiderMonkey JS Engine(COSCUP 2015) A Beginner's Journey to Mozilla SpiderMonkey JS Engine
(COSCUP 2015) A Beginner's Journey to Mozilla SpiderMonkey JS EngineZongXian Shen
 
Java applications containerized and deployed
Java applications containerized and deployedJava applications containerized and deployed
Java applications containerized and deployedAnthony Dahanne
 
Advanced Evasion Techniques by Win32/Gapz
Advanced Evasion Techniques by Win32/GapzAdvanced Evasion Techniques by Win32/Gapz
Advanced Evasion Techniques by Win32/GapzAlex Matrosov
 

Was ist angesagt? (20)

Using the Android Native Development Kit (NDK)
Using the Android Native Development Kit (NDK)Using the Android Native Development Kit (NDK)
Using the Android Native Development Kit (NDK)
 
Android ndk
Android ndkAndroid ndk
Android ndk
 
Using the android ndk - DroidCon Paris 2014
Using the android ndk - DroidCon Paris 2014Using the android ndk - DroidCon Paris 2014
Using the android ndk - DroidCon Paris 2014
 
Android NDK
Android NDKAndroid NDK
Android NDK
 
Android Developer Meetup
Android Developer MeetupAndroid Developer Meetup
Android Developer Meetup
 
Android ndk - Introduction
Android ndk  - IntroductionAndroid ndk  - Introduction
Android ndk - Introduction
 
How to implement a simple dalvik virtual machine
How to implement a simple dalvik virtual machineHow to implement a simple dalvik virtual machine
How to implement a simple dalvik virtual machine
 
PIC your malware
PIC your malwarePIC your malware
PIC your malware
 
Android NDK: Entrando no Mundo Nativo
Android NDK: Entrando no Mundo NativoAndroid NDK: Entrando no Mundo Nativo
Android NDK: Entrando no Mundo Nativo
 
Toward dynamic analysis of obfuscated android malware
Toward dynamic analysis of obfuscated android malwareToward dynamic analysis of obfuscated android malware
Toward dynamic analysis of obfuscated android malware
 
Understanding the Dalvik bytecode with the Dedexer tool
Understanding the Dalvik bytecode with the Dedexer toolUnderstanding the Dalvik bytecode with the Dedexer tool
Understanding the Dalvik bytecode with the Dedexer tool
 
How to reverse engineer Android applications
How to reverse engineer Android applicationsHow to reverse engineer Android applications
How to reverse engineer Android applications
 
Reverse engineering android apps
Reverse engineering android appsReverse engineering android apps
Reverse engineering android apps
 
FMXLinux Introduction - Delphi's FireMonkey for Linux
FMXLinux Introduction - Delphi's FireMonkey for LinuxFMXLinux Introduction - Delphi's FireMonkey for Linux
FMXLinux Introduction - Delphi's FireMonkey for Linux
 
Reverse Engineering Android Application
Reverse Engineering Android ApplicationReverse Engineering Android Application
Reverse Engineering Android Application
 
Accelerate your software development with Docker
Accelerate your software development with DockerAccelerate your software development with Docker
Accelerate your software development with Docker
 
Accelerate your development with Docker
Accelerate your development with DockerAccelerate your development with Docker
Accelerate your development with Docker
 
(COSCUP 2015) A Beginner's Journey to Mozilla SpiderMonkey JS Engine
(COSCUP 2015) A Beginner's Journey to Mozilla SpiderMonkey JS Engine(COSCUP 2015) A Beginner's Journey to Mozilla SpiderMonkey JS Engine
(COSCUP 2015) A Beginner's Journey to Mozilla SpiderMonkey JS Engine
 
Java applications containerized and deployed
Java applications containerized and deployedJava applications containerized and deployed
Java applications containerized and deployed
 
Advanced Evasion Techniques by Win32/Gapz
Advanced Evasion Techniques by Win32/GapzAdvanced Evasion Techniques by Win32/Gapz
Advanced Evasion Techniques by Win32/Gapz
 

Ähnlich wie Native development kit (ndk) introduction

Native Android for Windows Developers
Native Android for Windows DevelopersNative Android for Windows Developers
Native Android for Windows DevelopersYoss Cohen
 
제 4회 DGMIT R&D 컨퍼런스 : Android NDK
제 4회 DGMIT R&D 컨퍼런스 : Android NDK제 4회 DGMIT R&D 컨퍼런스 : Android NDK
제 4회 DGMIT R&D 컨퍼런스 : Android NDKdgmit2009
 
Exploring Next Generation Buildpacks - Anand Rao & Scott Deeg
Exploring Next Generation Buildpacks - Anand Rao & Scott DeegExploring Next Generation Buildpacks - Anand Rao & Scott Deeg
Exploring Next Generation Buildpacks - Anand Rao & Scott DeegVMware Tanzu
 
Getting started with the NDK
Getting started with the NDKGetting started with the NDK
Getting started with the NDKKirill Kounik
 
Building an Ionic hybrid mobile app with TypeScript
Building an Ionic hybrid mobile app with TypeScript Building an Ionic hybrid mobile app with TypeScript
Building an Ionic hybrid mobile app with TypeScript Serge van den Oever
 
Writing Android Libraries
Writing Android LibrariesWriting Android Libraries
Writing Android Librariesemanuelez
 
Yocto Project Dev Day Prague 2017 - Advanced class - Kernel modules with eSDK
Yocto Project Dev Day Prague 2017 - Advanced class - Kernel modules with eSDKYocto Project Dev Day Prague 2017 - Advanced class - Kernel modules with eSDK
Yocto Project Dev Day Prague 2017 - Advanced class - Kernel modules with eSDKMarco Cavallini
 
NCDevCon 2017 - Cross Platform Mobile Apps
NCDevCon 2017 - Cross Platform Mobile AppsNCDevCon 2017 - Cross Platform Mobile Apps
NCDevCon 2017 - Cross Platform Mobile AppsJohn M. Wargo
 
DLL Design with Building Blocks
DLL Design with Building BlocksDLL Design with Building Blocks
DLL Design with Building BlocksMax Kleiner
 
IBM Index 2018 Conference Workshop: Modernizing Traditional Java App's with D...
IBM Index 2018 Conference Workshop: Modernizing Traditional Java App's with D...IBM Index 2018 Conference Workshop: Modernizing Traditional Java App's with D...
IBM Index 2018 Conference Workshop: Modernizing Traditional Java App's with D...Eric Smalling
 
Going literate in Amadeus JUC Berlin June 25th 2014
Going literate in Amadeus JUC Berlin June 25th 2014Going literate in Amadeus JUC Berlin June 25th 2014
Going literate in Amadeus JUC Berlin June 25th 2014Vincent Latombe
 
Making your app soar without a container manifest
Making your app soar without a container manifestMaking your app soar without a container manifest
Making your app soar without a container manifestLibbySchulze
 

Ähnlich wie Native development kit (ndk) introduction (20)

Android ndk
Android ndkAndroid ndk
Android ndk
 
Getting Native with NDK
Getting Native with NDKGetting Native with NDK
Getting Native with NDK
 
Native Android for Windows Developers
Native Android for Windows DevelopersNative Android for Windows Developers
Native Android for Windows Developers
 
제 4회 DGMIT R&D 컨퍼런스 : Android NDK
제 4회 DGMIT R&D 컨퍼런스 : Android NDK제 4회 DGMIT R&D 컨퍼런스 : Android NDK
제 4회 DGMIT R&D 컨퍼런스 : Android NDK
 
Exploring Next Generation Buildpacks - Anand Rao & Scott Deeg
Exploring Next Generation Buildpacks - Anand Rao & Scott DeegExploring Next Generation Buildpacks - Anand Rao & Scott Deeg
Exploring Next Generation Buildpacks - Anand Rao & Scott Deeg
 
Getting started with the NDK
Getting started with the NDKGetting started with the NDK
Getting started with the NDK
 
1. react - native: setup
1. react - native: setup1. react - native: setup
1. react - native: setup
 
Building an Ionic hybrid mobile app with TypeScript
Building an Ionic hybrid mobile app with TypeScript Building an Ionic hybrid mobile app with TypeScript
Building an Ionic hybrid mobile app with TypeScript
 
109842496 jni
109842496 jni109842496 jni
109842496 jni
 
Writing Android Libraries
Writing Android LibrariesWriting Android Libraries
Writing Android Libraries
 
Yocto Project Dev Day Prague 2017 - Advanced class - Kernel modules with eSDK
Yocto Project Dev Day Prague 2017 - Advanced class - Kernel modules with eSDKYocto Project Dev Day Prague 2017 - Advanced class - Kernel modules with eSDK
Yocto Project Dev Day Prague 2017 - Advanced class - Kernel modules with eSDK
 
NCDevCon 2017 - Cross Platform Mobile Apps
NCDevCon 2017 - Cross Platform Mobile AppsNCDevCon 2017 - Cross Platform Mobile Apps
NCDevCon 2017 - Cross Platform Mobile Apps
 
Node.js
Node.jsNode.js
Node.js
 
DLL Design with Building Blocks
DLL Design with Building BlocksDLL Design with Building Blocks
DLL Design with Building Blocks
 
React nativebeginner1
React nativebeginner1React nativebeginner1
React nativebeginner1
 
Using the NDK and Renderscript
Using the NDK and RenderscriptUsing the NDK and Renderscript
Using the NDK and Renderscript
 
IBM Index 2018 Conference Workshop: Modernizing Traditional Java App's with D...
IBM Index 2018 Conference Workshop: Modernizing Traditional Java App's with D...IBM Index 2018 Conference Workshop: Modernizing Traditional Java App's with D...
IBM Index 2018 Conference Workshop: Modernizing Traditional Java App's with D...
 
tools cli java
tools cli javatools cli java
tools cli java
 
Going literate in Amadeus JUC Berlin June 25th 2014
Going literate in Amadeus JUC Berlin June 25th 2014Going literate in Amadeus JUC Berlin June 25th 2014
Going literate in Amadeus JUC Berlin June 25th 2014
 
Making your app soar without a container manifest
Making your app soar without a container manifestMaking your app soar without a container manifest
Making your app soar without a container manifest
 

Mehr von Rakesh Jha

Whitep paper on Emerging java and .net technology and critical trends
Whitep paper on Emerging java and .net technology and critical trendsWhitep paper on Emerging java and .net technology and critical trends
Whitep paper on Emerging java and .net technology and critical trendsRakesh Jha
 
Ways to be a great project manager
Ways to be a great project managerWays to be a great project manager
Ways to be a great project managerRakesh Jha
 
What is mobile wallet
What is mobile walletWhat is mobile wallet
What is mobile walletRakesh Jha
 
Cordova vs xamarin vs titanium
Cordova vs xamarin vs titaniumCordova vs xamarin vs titanium
Cordova vs xamarin vs titaniumRakesh Jha
 
Mobile applications testing (challenges, tools & techniques)
Mobile applications testing (challenges, tools & techniques)Mobile applications testing (challenges, tools & techniques)
Mobile applications testing (challenges, tools & techniques)Rakesh Jha
 
Mobile testing practices
Mobile testing practicesMobile testing practices
Mobile testing practicesRakesh Jha
 
Advanced programing in phonegap
Advanced programing in phonegapAdvanced programing in phonegap
Advanced programing in phonegapRakesh Jha
 
Introduction phonegap
Introduction phonegapIntroduction phonegap
Introduction phonegapRakesh Jha
 
Advanced JQuery Mobile tutorial with Phonegap
Advanced JQuery Mobile tutorial with Phonegap Advanced JQuery Mobile tutorial with Phonegap
Advanced JQuery Mobile tutorial with Phonegap Rakesh Jha
 
Basics of css3
Basics of css3 Basics of css3
Basics of css3 Rakesh Jha
 
Introduction to jquery mobile with Phonegap
Introduction to jquery mobile with PhonegapIntroduction to jquery mobile with Phonegap
Introduction to jquery mobile with PhonegapRakesh Jha
 
Basics of HTML5 for Phonegap
Basics of HTML5 for PhonegapBasics of HTML5 for Phonegap
Basics of HTML5 for PhonegapRakesh Jha
 
Introduction of phonegap installation and configuration of Phonegap with An...
Introduction of phonegap   installation and configuration of Phonegap with An...Introduction of phonegap   installation and configuration of Phonegap with An...
Introduction of phonegap installation and configuration of Phonegap with An...Rakesh Jha
 
User experience and interactions design
User experience and interactions design User experience and interactions design
User experience and interactions design Rakesh Jha
 
Android coding standard
Android coding standard Android coding standard
Android coding standard Rakesh Jha
 
Optimisation and performance in Android
Optimisation and performance in AndroidOptimisation and performance in Android
Optimisation and performance in AndroidRakesh Jha
 
Multithreading and concurrency in android
Multithreading and concurrency in androidMultithreading and concurrency in android
Multithreading and concurrency in androidRakesh Jha
 
Advance ui development and design
Advance ui  development and design Advance ui  development and design
Advance ui development and design Rakesh Jha
 
Android Design Architecture
Android Design ArchitectureAndroid Design Architecture
Android Design ArchitectureRakesh Jha
 
Android installation & configuration, and create HelloWorld Project
Android installation & configuration, and create HelloWorld ProjectAndroid installation & configuration, and create HelloWorld Project
Android installation & configuration, and create HelloWorld ProjectRakesh Jha
 

Mehr von Rakesh Jha (20)

Whitep paper on Emerging java and .net technology and critical trends
Whitep paper on Emerging java and .net technology and critical trendsWhitep paper on Emerging java and .net technology and critical trends
Whitep paper on Emerging java and .net technology and critical trends
 
Ways to be a great project manager
Ways to be a great project managerWays to be a great project manager
Ways to be a great project manager
 
What is mobile wallet
What is mobile walletWhat is mobile wallet
What is mobile wallet
 
Cordova vs xamarin vs titanium
Cordova vs xamarin vs titaniumCordova vs xamarin vs titanium
Cordova vs xamarin vs titanium
 
Mobile applications testing (challenges, tools & techniques)
Mobile applications testing (challenges, tools & techniques)Mobile applications testing (challenges, tools & techniques)
Mobile applications testing (challenges, tools & techniques)
 
Mobile testing practices
Mobile testing practicesMobile testing practices
Mobile testing practices
 
Advanced programing in phonegap
Advanced programing in phonegapAdvanced programing in phonegap
Advanced programing in phonegap
 
Introduction phonegap
Introduction phonegapIntroduction phonegap
Introduction phonegap
 
Advanced JQuery Mobile tutorial with Phonegap
Advanced JQuery Mobile tutorial with Phonegap Advanced JQuery Mobile tutorial with Phonegap
Advanced JQuery Mobile tutorial with Phonegap
 
Basics of css3
Basics of css3 Basics of css3
Basics of css3
 
Introduction to jquery mobile with Phonegap
Introduction to jquery mobile with PhonegapIntroduction to jquery mobile with Phonegap
Introduction to jquery mobile with Phonegap
 
Basics of HTML5 for Phonegap
Basics of HTML5 for PhonegapBasics of HTML5 for Phonegap
Basics of HTML5 for Phonegap
 
Introduction of phonegap installation and configuration of Phonegap with An...
Introduction of phonegap   installation and configuration of Phonegap with An...Introduction of phonegap   installation and configuration of Phonegap with An...
Introduction of phonegap installation and configuration of Phonegap with An...
 
User experience and interactions design
User experience and interactions design User experience and interactions design
User experience and interactions design
 
Android coding standard
Android coding standard Android coding standard
Android coding standard
 
Optimisation and performance in Android
Optimisation and performance in AndroidOptimisation and performance in Android
Optimisation and performance in Android
 
Multithreading and concurrency in android
Multithreading and concurrency in androidMultithreading and concurrency in android
Multithreading and concurrency in android
 
Advance ui development and design
Advance ui  development and design Advance ui  development and design
Advance ui development and design
 
Android Design Architecture
Android Design ArchitectureAndroid Design Architecture
Android Design Architecture
 
Android installation & configuration, and create HelloWorld Project
Android installation & configuration, and create HelloWorld ProjectAndroid installation & configuration, and create HelloWorld Project
Android installation & configuration, and create HelloWorld Project
 

Kürzlich hochgeladen

Mobile App Penetration Testing Bsides312
Mobile App Penetration Testing Bsides312Mobile App Penetration Testing Bsides312
Mobile App Penetration Testing Bsides312wphillips114
 
Mobile Application Development-Components and Layouts
Mobile Application Development-Components and LayoutsMobile Application Development-Components and Layouts
Mobile Application Development-Components and LayoutsChandrakantDivate1
 
Satara Call girl escort *74796//13122* Call me punam call girls 24*7hour avai...
Satara Call girl escort *74796//13122* Call me punam call girls 24*7hour avai...Satara Call girl escort *74796//13122* Call me punam call girls 24*7hour avai...
Satara Call girl escort *74796//13122* Call me punam call girls 24*7hour avai...nishasame66
 
Android Application Components with Implementation & Examples
Android Application Components with Implementation & ExamplesAndroid Application Components with Implementation & Examples
Android Application Components with Implementation & ExamplesChandrakantDivate1
 
Mobile Application Development-Android and It’s Tools
Mobile Application Development-Android and It’s ToolsMobile Application Development-Android and It’s Tools
Mobile Application Development-Android and It’s ToolsChandrakantDivate1
 

Kürzlich hochgeladen (6)

Mobile App Penetration Testing Bsides312
Mobile App Penetration Testing Bsides312Mobile App Penetration Testing Bsides312
Mobile App Penetration Testing Bsides312
 
Mobile Application Development-Components and Layouts
Mobile Application Development-Components and LayoutsMobile Application Development-Components and Layouts
Mobile Application Development-Components and Layouts
 
Satara Call girl escort *74796//13122* Call me punam call girls 24*7hour avai...
Satara Call girl escort *74796//13122* Call me punam call girls 24*7hour avai...Satara Call girl escort *74796//13122* Call me punam call girls 24*7hour avai...
Satara Call girl escort *74796//13122* Call me punam call girls 24*7hour avai...
 
Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)
Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)
Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)
 
Android Application Components with Implementation & Examples
Android Application Components with Implementation & ExamplesAndroid Application Components with Implementation & Examples
Android Application Components with Implementation & Examples
 
Mobile Application Development-Android and It’s Tools
Mobile Application Development-Android and It’s ToolsMobile Application Development-Android and It’s Tools
Mobile Application Development-Android and It’s Tools
 

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
  • 3. What is an NDK and Why NDK?
  • 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.
  • 20. Step 3: Implementing the Header file
  • 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.
  • 24. Step 4: Creating an Android.mk file
  • 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.
  • 28. Step 5: Compiling the native code
  • 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.
  • 31. Step 6: Calling native method
  • 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
  • 50. Creating and terminating native threads at Android NDK
  • 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); }
  • 61. Synchronizing native threads with conditional variables at Android NDK void *run_by_thread2(void *arg) { int* threadNum = (int*)arg; while (cnt < THR) { pthread_mutex_lock(&mux); if (cnt == THR2) { pthread_cond_signal(&cond); } else { ++cnt; LOGI(1, "thread %d: cnt = %d", *threadNum, cnt); } pthread_mutex_unlock(&mux); sleep(1); } }
  • 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)
  • 76. Synchronizing native threads with semaphore at Android NDK $ adb logcat -v time NativeThreadsSemaphore:I *:S
  • 77. Managing data for native threads at Android NDK
  • 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