在Android开发中,使用NDK开发越来越重要。如何在android studio中使用NDK开发,这里不再介绍,可以参考第一个ndk程序。在程序运行起来之后,接下来主要是要讲讲这个方法中相关代码的含义。
第一个程序分析
首先是引入了jni.h和string.h的头文件,作为jni的程序,引入jni的相关内容是必须的,同时,因为里面还用到了string的内容,所以也引入了string的头文件。
1 | #include <jni.h> |
接下来是extern "C"
,这个表示该函数实现 C 和 C++ 的混合编程,用于 C++ 代码调用 C 的函数。
然后看看具体的函数:
1 | JNIEXPORT jstring |
首先是第一句JNIEXPORT jstring
。JNIEXPORT
是一个宏定义,表明该函数可被外部调用,不定义时,默认也可以被外部调用,同时调用后返回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
指针,一个是jobject
。JNIEnv
是在jni.h中定义的结构体,表示jni环境,后续所有的jni接口都在里面,jobject
是调用者的对象。同时这里可以看到,jobject
后面没有具体的参数,这是一种省略的写法,后续如果要用到jobject,可以用this表示,当然你也可以自己补上jobject jo,然后操作jo。
看到这里,所有的jni方法都会有JNIEnv
和jobject
吗?不是。当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相关的概念,函数等相关内容。