安卓 java代码到jni_Android NDK 开发(一)JNI简介及调用流程

前言

前段时间学习了C、C++的一些基础知识后,了解了它们的编码风格,要想掌握NDK开发,前提是会使用JNI,下面我们开始简单的介绍吧!

JNI简介

JNI全称是Java Native Interface(Java本地接口),本地接口就是指用C和C++开发的接口。从Java1.1开始,JNI标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他编程语言,只要调用约定受支持就可以了。

开发JNI程序会受到系统环境的限制,因为用C/C++语言写出来的代码或模块,编译过程当中要依赖当前操作系统环境所提供的一些库函数,并和本地库链接在一起。而且编译后生成的二进制代码只能在本地操作系统环境下运行,因为不同的操作系统环境,有自己的本地库和CPU指令集,而且各个平台对标准C/C++的规范和标准库函数实现方式也有所区别。这就造成使用了JNI接口的JAVA程序,不再像以前那样自由的跨平台。如果要实现跨平台,就必须将本地代码在不同的操作系统平台下编译出相应的动态库。

JNI的开发流程主要分为以下几个步骤:

编写带有native声明方法的java类;

用”javac”命令来编译所编写的java类;

使用”javah”java类的名生成扩展名为h的头文件;

复制jni.h和jni_md.h文件到CPP工程中;

实现.h头文件中声明的函数

生成dll动态链接库

配置dll文件所在目录到环境变量

重启Eclipse

jni调用dill的流程图如下:

9f7fde50daaf6a4d75ebcd26738fb618.png

通过上面的分析,相信大家已经对jni的开发流程有一个整体的认识,接下来,我们将通过实例更进一步的了解。

第一步:编写带有native声明方法的java类

JniTest.java

package com.study.jni;

public class JniTest {

public native static String getStringFromC();

}

第二步:用”javac”命令来编译所编写的java类;

首先我们必须得配有java环境变量,然后我们右键点击项目->properties,复制项目路径;

e16692e7ea48901158fc413ac3b10e30.png

然后进入dos命令,

C:\Users\uuxuh>cd E:\Documents\11\JniTest

C:\Users\uuxuh>E:

E:\Documents\11\JniTest>cd src

E:\Documents\11\JniTest\src>

第三步:使用”javah”java类的名生成.h的头文件

接着,复制我们的完整类名(包名+类名),执行命令:

E:\Documents\11\JniTest\src>javah com.study.jni.JniTest

回到工程目录下,刷新项目,编译后的.h头文件就出现了。

源码:

com_study_jni_JniTest.h

/* DO NOT EDIT THIS FILE - it is machine generated */

#include

/* Header for class com_study_jni_JniTest */

#ifndef _Included_com_study_jni_JniTest

#define _Included_com_study_jni_JniTest

#ifdef __cplusplus

extern "C" {

#endif

/* * Class: com_study_jni_JniTest * Method: getStringFromC * Signature: ()Ljava/lang/String; */

JNIEXPORT jstringJNICALLJava_com_study_jni_JniTest_getStringFromC

(JNIEnv *, jclass);

#ifdef __cplusplus

}

#endif

#endif

第四步:复制jni.h和jni_md.h文件到CPP工程中

将要编译的文件中引入了

#inlcude

头文件,所以我们手动导入这两个文件到CPP工程中,

以我的jdk1.7.0_75为例,两个头文件的位置分别为:

jni.h jdk1.7.0_75/include

jni_md.h jdk1.7.0_75/include/linux

将我们生成.h头文件复制到项目的代码文件目录下 , 在解决方案中的头文件目录-> 右键-> 添加 -> 添加现有项 。 将我们的头文件添加进来,还有jni.h和jni_md.h一起添加进来,如图:

ca42e5bacc687ffc60d8cf2ce01347f9.png

第五步:实现.h头文件中声明的函数

c代码如下:

#include "com_study_jni_JniTest.h"

//函数实现

JNIEXPORT jstring JNICALL Java_com_study_jni_JniTest_getStringFromC

(JNIEnv *env, jclass jcls){

//简单的实现

//JNIEnv 结构体指针

//env二级指针

//代表Java运行环境,调用Java中的代码

//简单的实现

//将C的字符串转为一个java字符串

return (*env)->NewStringUTF(env, "C String");

}

第六步:生成dll动态链接库

我们以VS2013为例:

操作步骤:

选中项目 -> 右键 -> 属性 -> 常规 -> 项目默认值 -> 配置类型 , 选择动态库.dll,

bdeafbeacd939be82eb3112fb446d751.png

如图,右上角配置管理器,根据我们所使用的平台进去配置一下:

aed5e2ad6cbaab4bcca3817bff8df42f.png

这里我使用64位的,所以活动解决方案平台下新建了一个x64,部署项目配置也选择x64。

配置完了之后,最后生成解决方案。去项目目录下查看dll动态库。

c16e2bb28bc6b3c5aeb8a7e52045cb04.png

第七步:配置dll文件所在目录到环境变量

我们把生成dll文件的路径配置java环境变量里面,这样java 才会知道有dll动态库存在,配置完之后,重启下Eclipse。

最后我们在java中调用动态库,完整代码:

package com.study.jni;

public class JniTest {

public native static String getStringFromC();

public static void main(String[] args) {

System.out.println(getStringFromC());

}

// 加载动态库

static{

System.loadLibrary("jni_study");

}

}

最后运行一下项目控制台打印出C中返回给我们的字符串。

84f083d443f3eff385ec605f272c7022.png

好了,整个jni的调用流程已经说的非常详细了,但这只是jni入门的基础,后续会继续更新!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值