今天来了兴趣想更搞下JNI,于是乎拿起任玉刚的Android开发艺术看了会,看起来挺简单的,但是做的时候各种问题。经过自己的努力,也算是弄好了。那么就来和大家分享下。
这篇博客的所用的是Ubuntu14.04+android studio(1.0版本)+JDK1.8.x,因为这台电脑很久没用,所以是低版本。
接下来便按照任教主的方法来一步一步走下去,当让,其中会有很多坑。。。
package com.gl.jnidemo;
/** * Created by guolei on 15-10-31. */
public class JniTest {
static {
System.loadLibrary("jni-test");
}
public static void main(String args[]){
JniTest jniTest = new JniTest();
System.out.println(jniTest.get());
jniTest.set(" hello world jni");
}
public native String get();
public native void set(String str);
}
看到了目录结构,我们就开始了。首先我在这里不建议大家用as自带的终端来控制,因为我在用的时候出了点问题。
编译成class文件,首先进入到java文件夹下面。
在终端输入
javac com/gl/jnidemo/JniText.java
回车,我们进去包下面看看。
cd com/gl/jnidemo
ls
接下来就编译.h文件了。我们会退到java目录下
javac com.gl.jnidemo.JniText
或许上面这一句可以成功编译出.h头文件,但是很遗憾我没成,
别着急,试试下面的这一条
javac -classpath . -jni com.gl.jnidemo.JniText
如果上面的一条还是不行的话,那么 请去终端输入吧。
经过上面的步骤,已经成功生成.h头文件了。
我们看看生成的.h文件的代码
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_gl_jnidemo_JniTest */
#ifndef _Included_com_gl_jnidemo_JniTest
#define _Included_com_gl_jnidemo_JniTest
#ifdef __cplusplus
extern "C" {
#endif
/* * Class: com_gl_jnidemo_JniTest * Method: get * Signature: ()Ljava/lang/String; */
JNIEXPORT jstring JNICALL Java_com_gl_jnidemo_JniTest_get
(JNIEnv *, jobject);
/* * Class: com_gl_jnidemo_JniTest * Method: set * Signature: (Ljava/lang/String;)V */
JNIEXPORT void JNICALL Java_com_gl_jnidemo_JniTest_set
(JNIEnv *, jobject, jstring);
#ifdef __cplusplus
}
#endif
#endif
做一下简要说明
#include "com_gl_jnidemo_JniTest.h"
#include <stdio.h>
JNIEXPORT jstring JNICALL Java_com_gl_jnidemo_JniTest_get(JNIEnv *env, jobject thiz) {
printf("invoke get in c++\n");
return env->NewStringUTF("Hello from JNI !");
}
JNIEXPORT void JNICALL Java_com_gl_jnidemo_JniTest_set(JNIEnv *env, jobject thiz, jstring string) {
printf("invoke set from C++\n");
char* str = (char*)env->GetStringUTFChars(string,NULL);
printf("%s\n", str);
env->ReleaseStringUTFChars(string, str);
}
上面的函数名就是.h文件中的函数.
最后,我们生成.so文件,这里也是一个大坑。mac电脑上上午还能生成,下午来了就告我少个jni_md.h头文件。结果逼我跑到另一台电脑上搞。
gcc -shared -I JDK路径/include -fPIC test.cpp -o libjni-test.so
按照上面的格式在终端输入,比如我这里
gcc -shared -I /usr/lib/jvm/default-java/include -fPIC test.cpp -o libjni-test.so
JDK路径在as配置中看就好,回车,就生成的.so文件
java -Djava.library.path=../jni com.gl.jnidemo.JniTest
-Djava.library.path=so文件路径,请对照我最先给出的图。
最后,来张效果图,被电脑坑的不要不要的,弄出来自己也是很高兴。
好,今天就到这里了,祝大家学习愉快。