This shows you the differences between two versions of the page.
osp:lectures:lecture-ndk [2016/11/06 23:40] vlad.traista [Practical] |
osp:lectures:lecture-ndk [2017/01/22 11:38] (current) laura.ruse [Lecture] |
||
---|---|---|---|
Line 8: | Line 8: | ||
- | *{{:osp:lectures:lecture-ndk.pdf | Lecture Slides - Part 1}} | + | *{{:osp:lectures:lecture-ndk.pdf | Slides - Part 1}} |
+ | *{{:osp:lectures:6.ndk_notes.pdf | Notes - Part 1}} | ||
{{url>http://ocw.cs.pub.ro/courses/_media/osp/lectures/lecture-ndk.pdf}} | {{url>http://ocw.cs.pub.ro/courses/_media/osp/lectures/lecture-ndk.pdf}} | ||
- | *{{:osp:lectures:lecture-ndk-2.pdf | Lecture Slides - Part 2}} | + | *{{:osp:lectures:lecture-ndk-2.pdf | Slides - Part 2}} |
+ | *{{:osp:lectures:6.ndk2_notes.pdf | Notes - Part 2}} | ||
{{url>http://ocw.cs.pub.ro/courses/_media/osp/lectures/lecture-ndk-2.pdf}} | {{url>http://ocw.cs.pub.ro/courses/_media/osp/lectures/lecture-ndk-2.pdf}} | ||
Line 26: | Line 28: | ||
<note warning>If you do not have the Android NDK installed, you can downloand it and extract it from [[https://developer.android.com/ndk/downloads/index.html|this link]]. Afterwards in Android Studio you must set the NDK path if it is not set already. The path can be set by right clicking on the project and selecting the **Open Module Settings** menu item and setting the Android NDK location with a path similar to **/home/student/android-ndk-10re**. | <note warning>If you do not have the Android NDK installed, you can downloand it and extract it from [[https://developer.android.com/ndk/downloads/index.html|this link]]. Afterwards in Android Studio you must set the NDK path if it is not set already. The path can be set by right clicking on the project and selecting the **Open Module Settings** menu item and setting the Android NDK location with a path similar to **/home/student/android-ndk-10re**. | ||
+ | </note> | ||
+ | |||
+ | <note warning> | ||
+ | In order to successfully run an Android application with native support, you need to have [[http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html|Oracle Java 7 SDK]] installed and configure Android Studio to use that SDK. | ||
</note> | </note> | ||
=== Files === | === Files === | ||
- | {{:osp:lectures:nativeapplication.zip|}} | + | {{:osp:lectures:introapplication.zip|}} |
{{:osp:lectures:tasks.zip|}} | {{:osp:lectures:tasks.zip|}} | ||
+ | <note warning> | ||
+ | Abandon hope all ye who enter here for Android NDK is a mighty obstacle :D | ||
+ | </note> | ||
- | TODO - needs refactoring | ||
=== Task 1 - Create a Native Project (1p) === | === Task 1 - Create a Native Project (1p) === | ||
- | <note warning>Because NDK is not fully support on Android Studio yet, you will have to import the project from this archive: {{:osp:lectures:nativeapplication.zip|}} | + | <note warning>Because NDK is not fully support on Android Studio yet, you will have to import the project from this archive: {{:osp:lectures:introapplication.zip|}} |
You should use this whenever a new project is required. You can find more information about NDK integration in Android Studio at [[http://tools.android.com/tech-docs/new-build-system/gradle-experimental|this link]]. | You should use this whenever a new project is required. You can find more information about NDK integration in Android Studio at [[http://tools.android.com/tech-docs/new-build-system/gradle-experimental|this link]]. | ||
</note> | </note> | ||
- | Create a new project. | + | Edit native.cpp and add the following function: |
- | + | <code C++> | |
- | Edit native.c and add the following function: | + | extern "C" |
- | <code C> | + | jstring Java_com_example_user_nativeapplication_MainActivity_getString(JNIEnv *env, jobject instance) |
- | jstring Java_com_example_student_nativeapplication_MainActivity_getString(JNIEnv *env, jobject thiz) | + | |
{ | { | ||
- | return (*env)->NewStringUTF(env, "Hello world from JNI!"); | + | return env->NewStringUTF("Hello world from JNI!"); |
} | } | ||
</code> | </code> | ||
- | The equivalent C++ code is: | + | The equivalent C code is: |
- | <code C++> | + | <code C> |
- | extern "C" { | + | jstring Java_com_example_user_nativeapplication_MainActivity_getString(JNIEnv *env, jobject instance) |
- | jstring Java_com_example_student_nativeapplication_MainActivity_getString(JNIEnv *env, jobject thiz); | + | |
- | } | + | |
- | + | ||
- | jstring Java_com_example_student_nativeapplication_MainActivity_getString(JNIEnv *env, jobject thiz) | + | |
{ | { | ||
- | return env->NewStringUTF("Hello world from JNI!"); | + | return (*env)->NewStringUTF(env, "Hello world from JNI!"); |
} | } | ||
</code> | </code> | ||
Line 70: | Line 73: | ||
<code Java> | <code Java> | ||
static { | static { | ||
- | System.loadLibrary("native"); | + | System.loadLibrary("native-lib"); |
} | } | ||
Line 77: | Line 80: | ||
Then, make sure your activity has a TextView (with an id to reference it), and at onCreate, set the TextView to the String returned by getString(). | Then, make sure your activity has a TextView (with an id to reference it), and at onCreate, set the TextView to the String returned by getString(). | ||
- | |||
- | There is a more practical way of generating function prototypes: using javah or by automatically adding the functions using Android Studio. Declare all your native functions in the Java files first and then call javah to generate the headers. | ||
- | |||
- | For example: | ||
- | <code> | ||
- | javah -classpath <sdk>/platforms/android-23/android.jar:android_workspace/native/bin/classes/ com.example.student.nativeapplication.MainActivity | ||
- | </code> | ||
- | will generate com_example_student_nativeapplication_MainActivity.h | ||
- | which contains | ||
- | <code C> | ||
- | /* DO NOT EDIT THIS FILE - it is machine generated */ | ||
- | #include <jni.h> | ||
- | /* Header for class com_example_native1_MainActivity */ | ||
- | |||
- | #ifndef _Included_com_example_student_nativeapplication_MainActivity | ||
- | #define _Included_com_example_student_nativeapplication_MainActivity | ||
- | #ifdef __cplusplus | ||
- | extern "C" { | ||
- | #endif | ||
- | /* | ||
- | * Class: com_example_student_nativeapplication_MainActivity | ||
- | * Method: getString | ||
- | * Signature: ()Ljava/lang/String; | ||
- | */ | ||
- | JNIEXPORT jstring JNICALL Java_com_example_student_nativeapplication_MainActivity_getString | ||
- | (JNIEnv *, jobject); | ||
- | |||
- | #ifdef __cplusplus | ||
- | } | ||
- | #endif | ||
- | #endif | ||
- | </code> | ||
- | |||
=== Task 2 - Logging from Native Code (1p) === | === Task 2 - Logging from Native Code (1p) === | ||
- | To use logging from native code you will have to include **<android/log.h>**. Add this include to **native.c**. You will have to also link this module against liblog. This already done in the imported project (ldLibs += "log" in gradle.build). | + | To use logging from native code you will have to include **<android/log.h>**. Add this include to **native-lib.cpp**. You will have to also link this module against liblog. This already done in the imported project (ldLibs += "log" in gradle.build). |
Then, to print something, you need to use this macro: | Then, to print something, you need to use this macro: |