JNI学习笔记之Java端

来源:互联网 发布:数据完整性管理规程 编辑:程序博客网 时间:2024/06/05 05:31

最近公司新产品方案设计的时候在考虑用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了。

0 0