在NDK开发调用jni函数时,信息基本都是通过数据传递来实现。而且jni接口特别高冷,只要稍微
哪里不对,就会崩溃,把人都要整崩溃。我刚开始就时不时因为一个字母大小写错了,少写一个分号,怎么调都崩溃。所以想要高效开发,熟悉jni的数据类型尤为重要。
Jni常见Api:
JNIEnv:
指JNI的执行环境,是对Java虚拟环境的一个引用。在C中,我们能够看到JNIEnv的类型就是JNINativeInterface* 。而对于C++来说, _JNIEnv是一个结构体,里面包括了JNINativeInterface*的结构。
能够看到在它当中定义了非常多的函数指针,而通过这些定义。JNI层事实上就获得了对DVM的引用,通过定义的这些函数指针。能够定位到虚拟机中的 JNI 函数表,从而实现JNI层在DVM中的函数调用。
常用方法:
- FindClass
- GetMethodID
- GetFileID
- NewString
- NewStirngUTF
基本数据类型
引用类型
数组类型
java虚拟机类型
将JNI注册到Java时,会首先注册到Java虚拟机。最好是记住对应类型,也可以通过命令行的方式输出类型。
- 全限定类:
如lang包下的String类型,用 Ljava/lang/String;表示 (对象结尾加分号)
比如我项目包下有一个User类,那么就用 Lcom/example/ndkvaluepass/User;表示。
内部类:
该User有个Address内部类,那么Address类表示为:Lcom/example/ndkvaluepass/User$Address;
即内部类用$符号连接。
数组类型:
如[I 表示int类型的数组
[Lcom/example/ndkvaluepass/User; 表示User数组方法类型:(J + 第一个参数类型签名 + 第二个参数类型签名 + …)返回类型
1,返回类型为void的:
void setFocusPoint(const float x, const float y); 表示为:(JFF)V
void previewFile(const FileType type, const char* path, const int64_t offsetTime);
表示为: (JILjava/lang/String;J)V
2.返回类型为User数组的:
vector<User> getUserList();
(J)[Lcom/example/ndkvaluepass/User;
结构体示例:
struct SubtitleInfo {
enum SubtitleType type;
wchar_t* text;
char* fontFile;
int64_t fontColor;
int fontSize;
struct DisplayInfo displayInfo;
int64_t startTimeline;
int64_t endTimeline;
int64_t animationDuration;
enum SubtitleAnimationType animationType;
enum SubtitleAlignType alignType;
bool outlineFlag;
int64_t outlineColor;
int outlineSize;
bool shadowFlag;
int64_t shadowColor;
int shadowSize;
int shadowAngle;
bool scrollFlag;
bool previewFlag;
vector<struct DisplayInfo> displayInfos;
};
struct DisplayInfo {
int64_t time;
float centerX;
float centerY;
float width;
float height;
int rotate;
float alpha;
};
wchar_t,宽字符类型,是C/C++的字符类型,是一种扩展的存储方式,一般为16位或32位。
int64_t,64位平台下int表示
JNINativiMethod示例 :
public native String stringFromJNI();
public native void makeValue(int a,int b);
public static native void createUser(long player, int type, int id, String path, User user)
Java和JNI函数的绑定表:一定要睁大眼睛看好,一个字符错了都不行。
static JNINativeMethod player_methods[] = {
{ "stringFromJni" , "()Ljava/lang/String;" , (void*)stringFromJni },
{ "makeValue" , "(II)V" , (void*)makeValue },
{"createUser", "(JIILjava/lang/String;Lcom/example/ndkvaluepass/User;)V", (void*) createUser},
}
本篇讲的是jni数据类型,Jni完全参考手册。