ndk

NDK学习笔记(一)

Posted by alonealice on 2016-12-24

在Android开发中,使用NDK开发越来越重要。如何在android studio中使用NDK开发,这里不再介绍,可以参考第一个ndk程序。在程序运行起来之后,接下来主要是要讲讲这个方法中相关代码的含义。

第一个程序分析

首先是引入了jni.h和string.h的头文件,作为jni的程序,引入jni的相关内容是必须的,同时,因为里面还用到了string的内容,所以也引入了string的头文件。

1
2
#include <jni.h>
#include <string>

接下来是extern "C",这个表示该函数实现 C 和 C++ 的混合编程,用于 C++ 代码调用 C 的函数。

然后看看具体的函数:

1
2
3
4
5
6
7
8
JNIEXPORT jstring
JNICALL
Java_library_whitelife_hellojni_JniUtil_getString(
JNIEnv *env,
jobject /* this */) {
std::string hello = "哈哈哈哈";
return env->NewStringUTF(hello.c_str());
}

首先是第一句JNIEXPORT jstringJNIEXPORT是一个宏定义,表明该函数可被外部调用,不定义时,默认也可以被外部调用,同时调用后返回jstring。

jni里面一共有9中基本数据类型:jbyte、jchar、jshort、jint、jlong、jfloat、jdouble、jboolean、jstring,它们对应的java数据类型一目了然。

JNICALL也是一个宏定义,表示该函数是jni函数,当然,省略不写也没有影响。

然后看函数的名字:Java_library_whitelife_hellojni_JniUtil_getString。函数的名字很长,这是必须的。首先是表明该函数有java调用,调用的类第library_whitelife_hellojni_JniUtil,java类的完整路径,最后才是调用的natice方法名getstring,这些元素缺一不可。

再看传递的参数,一个是JNIEnv 指针,一个是jobjectJNIEnv是在jni.h中定义的结构体,表示jni环境,后续所有的jni接口都在里面,jobject是调用者的对象。同时这里可以看到,jobject后面没有具体的参数,这是一种省略的写法,后续如果要用到jobject,可以用this表示,当然你也可以自己补上jobject jo,然后操作jo。

看到这里,所有的jni方法都会有JNIEnvjobject吗?不是。当java层中的native方法为static方法时,会传入JNIEnv和jclass,jcalss表示的是调用的类。同时由于该方法在调用时不带参数,如果携带相关参数的话,jni方法也会有相关的参数,当然参数类型为转为jni的类型。

然后看具体的代码:

std::string hello = "哈哈哈哈"; std::是c++的命名空间,关于这方面的内容会在后续关于c++的文章中介绍。这个代码的意思相当于定义了一个string数据;然后调用了JNIEnv终端的函数env->NewStringUTF(hello.c_str());NewStringUTF是jni的方法,它通过传入字符串返回一个jstring对象,而c_str()函数则将string对象变成字符串

查看JNI方法

之前讲过,后续的jni方法基本都是通过JNIEnv来调用的,那么到底有哪些方法呢?首先你当然可以通过jni.h查看里面的源码,但是该文件很大,你可能很多的函数不一定能很快找到。最好的方式是通过java官网中的文档来查看相关的jni接口jni文档。里面包含了很多jni相关的概念,函数等相关内容。