code location
dalvik/libnativehelper/include/nativehelper/jni.h
frameworks/base/core/jni
android的JNI的调用过程中有个很重要的地方就是参数映射。体现在一个叫JNINativeMethod的结构体里面
JNINativeMethod在jni中有定义。
typedef struct {
const char* name;
const char* signature;
void* fnPtr;
} JNINativeMethod;
name对应java中的method name; signature是参数列表,由一串字符串表示,fnPtr是function pointer, 指向jni中的method。
最难理解的就是signature了,里面包含JAVA<——>C/C++之间的参数的map,即每个java类型,都有一个c/c++类型与之对应。
这些对应关系在
这段时间刚好看了蓝牙耳机部分,涉及到JNI调用,小小的总结一下。
JNI是JAVA Native Interface的缩写,意思是“JAVA 本地接口”。JNI帮助JAVA能和其它编程语言(C++ , C, 汇编)和库进行交互。
JNI的架构分为四个层次,应用程序---> JAVA框架(JAVA类(声明本地接口))---> JNI ---> C/C++本地库
JNI需要在JAVA源代码中声明,在C/C++中实现JNI的各种方法,并注册到系统中。
举例说明:在BluetoothHandsfree.java中,要简历蓝牙耳机的socket连接,调用下列语句
mIncomingSco = createScoSocket();
mIncomingSco.accept();
createScoSocket()创建一个ScoSocket对象,然后调用accept方法建立连接
1022 private ScoSocket createScoSocket() {
1023 return new ScoSocket(mPowerManager, mHandler, SCO_ACCEPTED, SCO_CONNECTED, SCO_CLOSED);
1024 }
在ScoSocket类里面
110 public synchronized boolean accept() {
//... 省略无关语句
116 if (acceptNative()) {
117 mState = STATE_ACCEPT;
118 return true;
119 }
//... 省略无关语句
123 }
这里面的acceptNative()就是个JNI方法,在ScoSocket类里面声明并调用
124 private native boolean acceptNative();
这个方法在/frameworks/base/core/jni/android_bluetooth_ScoSocket.cpp内实现,并且注册到系统中
675 static JNINativeMethod sMethods[] = {
//... 省略无关语句
680 {"acceptNative", "()Z", (void *)acceptNative},
682 };
JNINativeMethod结构体是JNI的核心,在jni.h里面定义
“acceptNative”:JNI函数的名称
“()Z”JNI函数的参数和返回值,"()"填的是参数(这里为空)例如:Ljava/lang/String; I 参数之间用分好隔开,这些大写字母(L, Z...)在JAVA和JNI里面都有对应的类型,L对应JAVA 对象,JNI的jobject类型; Z对应JAVA的boolean类型, JNI的jboolean类型。
然后向AndroidRuntime注册这些Native方法
684 int register_android_bluetooth_ScoSocket(JNIEnv *env) {
685 return AndroidRuntime::registerNativeMethods(env,
686 "android/bluetooth/ScoSocket", sMethods, NELEM(sMethods));
687 }
AndroidRuntime.cpp与android_bluetooth_Socket.cpp处于同一目录
它会调用register_android_bluetooth_ScoSocket(JNIEnv *env)进行注册
注册过程在启动虚拟机之后开始
int AndroidRuntime::startReg(JNIEnv* env)
//... 省略无关代码
1312 if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
1313 env->PopLocalFrame(NULL);
1314 return -1;
1315 }
//... 省略无关代码
1321 }
static const RegJNIRec gRegJNI[] = {
//... 省略无关代码
REG_JNI(register_android_bluetooth_BluetoothSocket),
}
REG_JNI 是一个宏定义,对注册函数进行包装
1155 #define REG_JNI(name) { name, #name }
1156 struct RegJNIRec {
1157 int (*mProc)(JNIEnv*);
1158 const char* mName;
1159 };
来源:CSDN
作者:holaJohnny
链接:https://blog.csdn.net/yinlijun2004/article/details/6065391