您的位置:首页 > 移动开发 > Android开发

Android JNI/NDK 简单使用

2017-01-06 23:20 155 查看
jni是java本身就支持的,现在Android如果要用原生的话,
会比较麻烦,所以Android弄了个NDK,是为了更方便使用jni的。所以我下面讲的是在Eclipse里使用NDK的案例。


一.首先,下载个NDK,解压放到合适的位置。

二. 然后我们配置下NDK的环境,

打开eclipse–>选择Window–>Preferences–>选中Android,展开—->点NDK—- >在右边NDK Location里输入解压的那个NDK的根目录

比如说:D:\android-ndk-r13b

但报错说不是一个有效的目录,这时候,我们要在解压的那个NDK的根目录下新建一个空文件,名字叫ndk-build.然后重新再输入路径就不会出错了。

三. 创建个项目,选中项目,右键—》Android Tools—》Add Native Surport。

随便起个名,这个就是动态链接库的名字,finish,这个时候在项目里就会自动添加obj文件夹和jni文件夹,我们主要关注jni文件夹,obj文件夹是存放C/C++编译出来的文件的。jni里有一个Android.mk文件,和一个默认的.cpp文件,这个文件就是用来写c++代码的。编译一下项目你会发现有多了一些莫名其妙的东西。

因为这个.cpp里的东西怎么写要看调用者是什么,所以我们从调用者那里开始理一下使用方法。

比如说:我想在MainActivity.java 这个类里求两数的和,但是因为这个求和代码非常需要效率,所以我希望用C++代码实现,然后我来调用C++里的方法。

然后我希望C++代码里有个addNum方法传两个参数。

那么,首先,我要把那个人叫过来,就是加载动态链接库

static{
System.loadLibrary("Test");
}


这个一般写在静态区,然后那个Test就是创建的那个动态链接库的名字

如果C++里有这个addNum方法,然后我直接调用它,这是不可能的,编译器找不到这个方法,所以我们要先编译器,我在其他地方有这个方法,我可以去调用。

就是这样定义一下这个方法

private native int addNum(int a,int b);


然后,你再调用这个方法,比如叫那个人帮你算1+1;

int i = addNum(1, 1);


但是这样还是没法调用C++里的方法,我们还需要让调用C++方法的Java类生成一个头文件。然后让C++那个类include这个头文件。

这个有点像信物啊!哈哈!

你拿着这块玉佩去找当今的武林盟主。然后叫他帮你算道数学题。

这个jni的机制不太懂,我乱说的。

四. 怎么生成这个头文件呢,要用到jdk里的javah.exe.。

我们打开windows的cmd

进入项目的src目录,执行

javah com.hyw.test.MainActivity


其中,com.hyw.test.MainActivity是要生成头文件的全类名,注意不用.java或.class哦。

这时候在项目的src文件目录下就会生成以.h结尾的头文件了,如果有内部类的话会生成多个。注意文件名很有意思,就要这样的哦。(全类名把点换成下划线)。

点进去发现报错,这是因为那个jni.h找不到,那么,我们就要告诉他在哪

eclipse菜单栏 —-》project—-》Properties—–》C/C++ General —–》 Paths and Symbols —-》add—-》

在弹出框的那个框框里输入ndk目录下的这个目录

android-ndk-r13b\platforms\android-24\arch-arm64\usr\include


当然,要灵活变通

可以用那个file system选,注意上面那个不是完整路径,下面这个才是

D:\android-ndk-r13b\platforms\android-24\arch-arm64\usr\include


确定再确定,错误不见了。

回到正题,为了方便那个C++文件include头文件,我们把头文件移到jni文件夹,其实生成的时候就可以指定文件夹的,不过我忘了怎么弄了

五. 我们在那个c++文件里这样导入

#include <com_hyw_test_MainActivity.h>


然后我们要写那个方法了,这里有个问题就是jni里的数据类型跟Java的是不一样的,看图



所以方法里的类型名会有一些不同,其实有很多奇怪的地方,

jint Java_com_hyw_test_MainActivity_addNum
(JNIEnv *env, jobject obj, jint a, jint b){
return a+b;
}


返回类型是jint

方法名是这样写的哦,注意前面还有个Java_

JNIEnv *env 跟 jobject obj这两个参数是默认需要的

打完收工。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android jni ndk eclipse