最近公司新产品方案设计的时候在考虑用JNI,奈何从来没用过JNI,于是网上大肆找教程,对比几篇后发现这一篇教程不错,在这里贴上链接:
http://www.cnblogs.com/youxilua/archive/2011/09/16/2178554.html
首先了解一下Android平台框架,Android平台分为:
Application ------> 程序应用层
Application FrameWork ------> 应用程序框架
Libraries\Android Runtime ------> Android程序库/运行库
Linux Kernel ------> Linux 内核
上层的Application和Application FrameWork都是使用Java语言编写的,而底层,包括系统和Libraries都是使用C\C++编写的,所以上层Java要调用底层的C\C++函数库必须通过Java的JNI来实现。
JNI的原理图我也看不懂,先贴出来吧
那么如何使用JNI呢?
首先在java端编写一个.java文件,用记事本也好,eclipse也好,as也好,我还没试在android studio编写JNI,因为公司现在用的还是eclipse,T_T
package com.example.testjni;
public class TestJNI {
public native int nativeFileOpen(String name);
public native int nativeFileRead(int resultCode, byte[] inputData,
int length);
public native int nativeFileWrite(int resultCode, byte[] inputData,
int length);
public native int nativeFileClose(int resultCode);
}
写好这个.java文件后,可以用cmd编译javac TestJNI.class生成.class文件,其实一直觉得用记事本和cmd写程序的人才是无形装逼,毕竟情怀,用eclipse的话运行一次就会自己在bin\classes目录下自己生成.class文件啦,然后在cmd中javah TestJNI利用生成的.class文件生成.h文件,注意,这里文件名不要加.class后缀,而且不能在当前目录下,要在当前包的上一层目录,这时候记得文件名前面加上类名,具体情况如下图:
可见编译.class文件是在.java文件所在的目录下,但是编译.h时,在.class的文件所在目录下直接编译却报错了,找不到‘TestJNI’的类文件,于是退到包的上一层目录,即src目录,再执行javah TestJNI,还是找不到,所以这时候记得加上包名,javah com.example.testjni.TestJNI,就成功了,这时就会在src目录下生成com_example_testjni_TestJNI.h这个文件,然后把这个文件交给C语言端去编写。
貌似在eclipse中可以快速开发JNI,一键生成.h文件的,不过我试了没有成功,不知道是不是环境问题,附上一个友情链接:
https://www.oschina.net/question/1402563_133543
由于我不会写C语言,C语言端这里就不瞎BB啦,再说说如何使用JNI。
将C语言编译生成的.so文件放在libs下的armeabi文件夹(没有则新建一个)中,在需要用到JNI的地方插入以下代码
static {
<span style="white-space:pre"> </span> System.loadLibrary("TestJNI");
}
TestJNI替换为你的JNI库名,注意没有前面的lib和.so后缀,然后创建JNI对象就可以调用JNI中的方法了。
以上就是JNI的最基本最基本的用法,下面说一个我遇到的问题,在编写下面这个JNI时,
package com.example.testjni;
import android.view.Surface;
public class TestJNI {
public static native int setSurface(Surface surface);
public static native int startDraw();
public static native int stopDraw();
}
会报一个找不到类android.view.Surface的错误,但是这个类android源生的类,我们没必要将源码拷贝出来,这个问题主要是因为没有和android里面的class连接造成的,如何解决:
在sdk\platform目录下随便找一个版本(我选的是android-23)的目录进去,复制android.jar在当前目录即可,改名为android.rar,解压为名为一个android的文件夹(右键--->解压到android即可),然后删掉android.rar,复制文件夹的目录,在环境变量中的classpath变量中加入该目录即可,各目录之间要用;隔开,重启cmd,OK了。