JNI函数的参数也由三部分组成:首先是JNIEnv *,是一个指向JNI运行环境的指针;第二个参数随本地方法是静态还是非静态而有所不同一一非静态本地方法的第二个参数是对对象的引用,而静态本地方法的第二个参数是对其Java类的引用;其余的参数对应通常Java方法的参数,参数类型需要根据一定规则进行映射。

(4)编写相应方法的实现代码

在编码过程中,需要注意变量的长度问题,例如Java的整型变量长度为32位,而C语言为16位,所以要仔细核对变量类型映射表,防止在传值过程中出现问题。

(5)将JNI实现代码编译成动态链接库

编译过程是利用C/C++编译器实现的,当要使用生成的动态链接库时,调用者类中需要显式调用该链接库。

经过上述处理,基本上完成了一个包含本地化方法的Java类的开发。

3 基于JNI的嵌入式手机软件开发实例

下面通过一个实例来描述运用JNI技术在手机上操纵摄像头,捕捉视频并存储图片的过程。

(1)活动/状态图

图2为捕捉视频并存储图片的活动/状态图

根据图2的活动/状态,具体的对应步骤如下:

①发起该流程。

②发起流程后,建立文件用于存储图片。

③用指针获得分配的缓冲器,用于存储获得的帧。

④将指针压栈(序列化缓冲器)。由于手机的内存较小,为了防止内存泄漏,Symbian操作系统有一个Cleanup stack的要求,即在使用指针时,用PushL把指针压入栈中,使用完后再用Pop弹出栈.如果在中间调用导致崩溃的函数时果真出现了问题,那么Clean up stack可以通过调用该指针的析构函数回收占用的空间。

⑤操纵摄像头,捕捉视频,并将图像流从摄像头端传到缓冲器。

⑥将摄像头内的图像流存入缓冲器内,并将缓冲器内的流转化为文件流,存为jpg格式的文件,将指向缓冲器的指针弹栈。

⑦在过程⑥中,如果使用完了序列化的缓冲器,则要重新序列化缓冲器,以备后面使用。

⑧当接收到停止视频捕捉的信号后,关闭文件。

⑨流程结束。

基于嵌入式软件的JNI技术应用解析

(2)运用JNI技术的视频捕捉

子功能捕捉视频的实现是由操纵摄像头、视频播放(解码器准备)以及建立摄像头和手机之间的连接会话三个活动组成的。其中操纵摄像头是通过调用底层设备的驱动来实现的,需要利用JNI来实现,完成的方法包括准备、建立、删除、销毁摄像头等。视频播放的一系列过程也是通过c++代码来实现的,除了准备、建立、删除、销毁解码器外,还有开始、暂停、停止解码等。建立摄像头和手机之间的连接类似建立客户端和服务器连接,视频流从摄像头传到手机界面是通过多媒体会话来完成的。多媒体会话的建立、关闭、摧毁以及会话建立后的发送、取消、读取数据等也是JNI的应用范畴。