Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jni Tutorial for android [closed]

Hi, can anyone suggest me some good resources to learn JNI for Android and some good JNI Tutorials?

like image 837
Vishwanath.M Avatar asked Apr 14 '11 05:04

Vishwanath.M


People also ask

How does JNI work on Android?

It defines a way for the bytecode that Android compiles from managed code (written in the Java or Kotlin programming languages) to interact with native code (written in C/C++). JNI is vendor-neutral, has support for loading code from dynamic shared libraries, and while cumbersome at times is reasonably efficient.

What is Jniexport Jnicall?

JNIEXPORT ensures function is visible in the symbols table. JNICALL ensures function uses the correct calling convention. On Android JNICALL has a different value based on architecture. ARM is empty which might trick you to not include it. But you must use JNICALL.

What is JNIEnv * env?

jobject NewGlobalRef(JNIEnv *env, jobject obj); Creates a new global reference to the object referred to by the obj argument. The obj argument may be a global or local reference.


1 Answers

Tutorial for ECLIPSE

Here is first and second small tutorials, but if you want to write a simple program that uses JNI , you may continue reading :)

Create Android application project , Once your project has been created, you’ll need to create a new folder inside the top level of the project. To do this right click on your project name → New → Folder. Name this folder jni. Than add class with name SquaredWrapper. add these code in it

package org.edwards_research.demo.jni;  public class SquaredWrapper {     // Declare native method (and make it public to expose it directly)     public static native int squared(int base);      // Provide additional functionality, that "extends" the native method     public static int to4(int base)     {         int sq = squared(base);         return squared(sq);     }      // Load library     static {         System.loadLibrary("square");     } }  

Open terminal. You must compile these code for getting header file. At first call this command.

cd src # change into the source directory javac -d /tmp/ org/edwards_research/demo/jni/SquaredWrapper.java 

Than

cd /tmp javah -jni org.edwards_research.demo.jni.SquaredWrapper 

SO you'll have header file named org.edwards_research.demo.jni.SquaredWrapper in your tmp directory.

it must be something like this

/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class org_edwards_research_demo_jni_SquaredWrapper */  #ifndef _Included_org_edwards_research_demo_jni_SquaredWrapper #define _Included_org_edwards_research_demo_jni_SquaredWrapper #ifdef __cplusplus extern "C" { #endif /*  * Class:     org_edwards_research_demo_jni_SquaredWrapper  * Method:    squared  * Signature: (I)I  */ JNIEXPORT jint JNICALL Java_org_edwards_1research_demo_jni_SquaredWrapper_squared   (JNIEnv *, jclass, jint);  #ifdef __cplusplus } #endif #endif 

change these name for some short one for your comfort, for example square.h. Copy this header file in the jni folder of your app. Than create square.c file in same folder, copy this in it.

 #include "square.h"  JNIEXPORT jint JNICALL Java_com_example_android_1jni_1second_1demo_SquaredWrapper_squared       (JNIEnv * je, jclass jc, jint base)     {             return (base*base);     } 

Add this in your MainActivity.java

int x = SquaredWrapper.to4(2);         x = x*2; 

Add Android.mk file in jni folder with this body

    LOCAL_PATH := $(call my-dir)  include $(CLEAR_VARS)  LOCAL_MODULE    := squared LOCAL_SRC_FILES := square.c  include $(BUILD_SHARED_LIBRARY) 

It must create library from header and cpp files.

So you have only to do some configurations by looking on my first link Now you can compile it , be sure that your library has created and your lib directory consist it.

Tutorial for Android Studio

Let's consider you have simple android application opened by Android Studio

step 1: open Your application by Android Studio

step 2: Download NDK and set the path to NDK in local properties of your application(below/above of android sdk path) like this ndk.dir=C\:\\Android\\android-ndk-r10e

P.S. for windows double // , for linux one /

step3: Add JNI folder in the app (right click on the app -> new -> folder -> JNI Folder)

step 4 Set up the Gradle by this way:

Add this code in app/build.gradle for starting NDK

   sourceSets.main {         jni.srcDirs = []         jniLibs.srcDir 'src/main/libs'     }      tasks.withType(NdkCompile) { // disable automatic ndk-build call     compileTask -> compileTask.enabled = false     }      task ndkBuild(type: Exec) { // call ndk-build(.cmd) script         if (Os.isFamily(Os.FAMILY_WINDOWS)) {             commandLine 'cmd', '/c', 'ndk-build.cmd', '-C', file('src/main').absolutePath         } else {             commandLine 'ndk-build', '-C', file('src/main').absolutePath         }     tasks.withType(JavaCompile) {         compileTask -> compileTask.dependsOn ndkBuild     } 

step 4:

Create files Android.mk and Application.mk in JNI folder of the app with this bodies:

Android.mk

LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := main LOCAL_SRC_FILES := main.cpp  include $(BUILD_SHARED_LIBRARY) 

Application.mk

APP_ABI := all include $(BUILD_SHARED_LIBRARY) 

In APP_ABI you choose which compilers to use. It

step 5:

We have to manually run NDK as we disable it from build.config. For creating com_example_nativedemo_app_MainActivit.h file in src\main\jn folder we have to run this command in terminal

javah -d .\jni -classpath C:\Intel\INDE\IDEintegration\android-sdk-windows\platforms\android-21\android.jar;..\..\build\intermediates\classes\debug com.example.mydemo.nativedemo.MainActivity 

for windows cmd you have to give the full path of files. For

step 6:

Add file main.cpp in JNI folder with this body:

#include <string.h> #include <jni.h> #include <vchat_cpptest_Hellojnicpp.h>  extern "C" {       JNIEXPORT jstring JNICALL       Java_vchat_cpptest_Hellojnicpp_stringFromJNI       (JNIEnv *env, jobject obj)       {             #ifdef __INTEL_COMPILER_UPDATE               return env->NewStringUTF("Hello from Intel C++ over JNI!");           #else               return env->NewStringUTF("Hello from default C++ over JNI!");           #endif } 
like image 185
Hayk Nahapetyan Avatar answered Sep 21 '22 00:09

Hayk Nahapetyan