0%

android_jni

a example of JNI static way:

first step: write a middle java file:

mkdir jni
cd jni/
vim TestJni.java

import java.util.*;
public class TestJni
{
    public native void xprint(String content);
    static
    {
        System.loadLibrary("TestJni");
    }
}

javac TestJni.java and make a class

then
javah -jni TestJni to make a .h file:

  /* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class TestJni */

#ifndef _Included_TestJni
#define _Included_TestJni
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     TestJni
 * Method:    xprint
 * Signature: (Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_TestJni_xprint
  (JNIEnv *, jobject, jstring);

#ifdef __cplusplus
}
#endif
#endif

step two write jni file.c:

TestJni.c:

#include<jni.h>
#include<stdio.h>
#include "TestJni.h"

JNIEXPORT void JNICALL Java_TestJni_xprint(JNIEnv *env,jobject obj,jstring content)
{
    const jbyte *str=(const jbyte*)(*env)->GetStringUTFChars(env,content,JNI_FALSE);
    printf("hello--wo%s \n",str);
    (*env)->ReleaseStringUTFChars(env,content,(const char*)str);
    return;
}

three build .so lib

cc -I/usr/jdk-8/include/ -I/usr/jdk-8/include/linux/ -I .../jni/ -fPIC -shared -o libTestJni.so TestJni.c

four write a test:hellow.java

import java.util.*;
public class hellow
{
    public static void main(String argc[])
    { 
        new hellow();
    }
    public hellow()
    { 
       new TestJni().xprint("hi my name is keee");
    }
}

question:

如果你这步发生问题,如果这步你收到java.lang.UnsatisfiedLinkError异常,可以通过如下方式指明共享库的路径:

java -Djava.library.path=’.’ HelloWorld
或者输入命令:
export LD_LIBRARY_PATH=“HelloWorld路径”:$LD_LIBRARY_PATH 设置环境变量

然后再 java HelloWorld 一样OK

reference

http://www.cnblogs.com/bastard/archive/2012/05/17/2506877.html
http://www.cnblogs.com/wzben/p/5733571.html

a example of JNI dynamic way:

step 1:

write a TestJni.java

public class SimpleJni{
    static {
        System.out.println("[java] static code block,start load shared library...");
        System.loadLibrary("SimpleJni");
        System.out.println("[java]load library end...");
    }
    static native int add(int a,int b);
    public static void main(String args[])
    {
        System.out.println("[java] in main...");
        System.out.println("[java] 3+4="+SimpleJni.add(3,4));
        System.out.println("end...");
    }
}

step 2:

write a Jni file:
#include <jni.h>
#include<stdio.h>
const char *classPathName=”com/bt/jni/SimpleJni”;

jint myadd(JNIEnv *env,jobject thiz,jint a,jint b)
{
    return a+b;
}
static JNINativeMethod methods[]={
    {"add","(II)I",(void*)myadd},};
int registerNatives(JNIEnv *env)
{
    jclass clazz;

    clazz=(*env)->FindClass(env,classPathName);
    if(NULL==clazz){
       printf("[C] FindClass fail\n");
       goto failed;
    }
     if (0>(*env)->RegisterNatives(env,clazz,methods,sizeof(methods)/sizeof(methods[0]))){
         printf("RegisterNatives fail.\n");
         goto failed;
     }
     return JNI_TRUE;
failed:
     return JNI_FALSE;
}


jint JNI_OnLoad(JavaVM *vm,void *reserved)
{
    JNIEnv *env=NULL;
    jint result=-1;
    void **env_p=NULL;

    printf("start register native func\n");
    env_p=(void**)&env;

    if(JNI_OK!=(*vm)->GetEnv(vm,env_p,0x00010006)){
        printf("get env failed..\n");
        goto err;
    }
    if(JNI_TRUE!=registerNatives(env)){
        printf("register fail...exit....\n");
        goto err;
    }
    result=0x00010006;
err:
    return result;
}

step use:

1.首先编写SimpleJni.java和simpel_jni.c
2.编译java和c文件
$ java -d . SimpleJni.java
$gcc -fPIC -I$JAVA_HOME/include/ -I$JAVA_HOME/include/linux/ -o libsimpleJni.so simple_jni.c

3.执行
$java -Djava.library.path=. com.bt.jni.SimpleJni

other example:

java file:
import java.util.*;
public class TestJni
{
public native void xprint(String content);
static
{
System.loadLibrary(“TestJni”);
}
public native static String native_hello();
}

JNI file:

#include<jni.h>
#include<stdio.h>
//#include "TestJni.h"
#include<iostream>
using namespace std;
 void xprint(JNIEnv *env,jobject obj,jstring content)
{  
//    const jbyte *str=(const jbyte*)(env->GetStringUTFChars(env,content,JNI_FALSE));
    //printf("hello--wo%s \n",str);
//    env->ReleaseStringUTFChars(env,content,(const char*)str);
        cout<<"here:"<<content<<endl;
    return;
}
static jstring  native_hello(JNIEnv *env,jobject object)
{ 

    
    return (env)->NewStringUTF("keshixi");
}

static JNINativeMethod method_table[]={
    { "xprint","(Ljava/lang/String;)V",(void*)xprint},
    {"native_hello","()Ljava/lang/String;",(void*)native_hello}
//    {,,(void*)xprint},{,,(void*)native_hello}
};

 jint JNI_OnLoad(JavaVM *jvm,void *reserved){
    JNIEnv *env;
    if(jvm->GetEnv((void**)&env,JNI_VERSION_1_6)!=JNI_OK){
        return -1;
    }
    jclass clz=env->FindClass("TestJni");
    if(clz==NULL)
    {
        return JNI_FALSE;
    }
    if(env->RegisterNatives(clz,method_table,sizeof(method_table)/sizeof(method_table[0]))==JNI_OK){
        return JNI_VERSION_1_6;
    }
  }

####reference:
jni有两种使用方式,一种是静态注册的,依赖于头文件的。另一种是动态注册的不依赖头文件,静态的看里面文件夹的实例和博客就行

动态方式也可以参见dy文件夹下的网页教程,以及对应的两个例子

另外可以作为ndk在android中使用及在android stdio也可以直接生成so

一些链接:android_jni_ndk:http://www.cnblogs.com/wzben/p/5733571.html
动态注册无运行实例:http://www.linuxidc.com/Linux/2017-02/140130.htm
静态注册:http://www.cnblogs.com/bastard/archive/2012/05/17/2506877.html
动态注册:有实例http://www.linuxidc.com/Linux/2017-02/140129.htm

www.fer.unizg.hr/_download/repository/jni.pdf文档