怎样申请做p2p融资网站,自助商城,wordpress怎么弄,wordpress如何加html在android代码中#xff0c;经常可以看到native方法#xff0c;需要查看其对应的C方法#xff0c;这些方法是一一对应的#xff0c;对应关系是在jni注册里关联起来的。
比较直观的是这样的例子#xff0c;
Parcel.java
//Java层的方法里调用了native方法nativeWriteInt…
在android代码中经常可以看到native方法需要查看其对应的C方法这些方法是一一对应的对应关系是在jni注册里关联起来的。
比较直观的是这样的例子
Parcel.java
//Java层的方法里调用了native方法nativeWriteInt(mNativePtr, val) public final void writeInt(int val) { nativeWriteInt(mNativePtr, val); }
//Java层中声明了native方法 private static native void nativeWriteInt(long nativePtr, int val); private static native void nativeWriteLong(long nativePtr, long val); 以 nativeWriteInt方法为例进而会调用到frameworks/base/core/jni/android_os_Parcel.cpp中的android_os_Parcel_writeInt方法。
搜nativeWriteInt可以看到{nativeWriteInt, !(JI)V, (void*)android_os_Parcel_writeInt}
以{nativeWriteInt, !(JI)V, (void*)android_os_Parcel_writeInt}为例
nativeWriteInt是Java层Parcel.java中声明的函数名称而android_os_Parcel_writeInt是JNI层android_os_Parcel.cpp中对应的函数。
!(JI)V是函数签名对函数的参数和返回值进行标记采用了函数签名即便是重载了的同名函数都可以通过函数签名来进行区分。
通过这样的映射处理Java层就和Native层关联起来了。
通过RegisterMethodsOrDie(env, kParcelPathName, gParcelMethods, NELEM(gParcelMethods))调用最终来实现了JNI方法的关联。android.os.Parcel类中的nativeWriteInt方法对应着android_os_Parcel.cpp中的static void android_os_Parcel_writeInt(JNIEnv* env, jclass clazz, jlong nativePtr, jint val)方法。
static void android_os_Parcel_writeInt(JNIEnv* env, jclass clazz, jlong nativePtr, jint val) { Parcel* parcel reinterpret_castParcel*(nativePtr); if (parcel ! NULL) { const status_t err parcel-writeInt32(val); if (err ! NO_ERROR) { signalExceptionForError(env, clazz, err); } }
}
android_os_Parcel_writeInt方法中又调用了C层的Parcel类进而通过JNI实现了Java层对C层方法的调用。 gParcelMethods是JNINativeMethod类型的数组存储了Java层函数和native函数的映射关系。 还有一种不太直观的描述
比如libcore/ojluni/src/main/java/java/net/NetworkInterface.java
里的
393 private static NetworkInterface[] getAll() throws SocketException {
394 // Group Ifaddrs by interface name.
395 MapString, ListStructIfaddrs inetMap new HashMap();
396
397 StructIfaddrs[] ifaddrs;
398 try {
399 ifaddrs Libcore.os.getifaddrs();
400 } catch (ErrnoException e) {
401 throw e.rethrowAsSocketException();
402 }
这里查找getifaddrs方法的实现找到Libcore.java
继续找到libcore/luni/src/main/java/libcore/io/Linux.java public native StructIfaddrs[] getifaddrs() throws ErrnoException;
是个native方法具体的实现是哪里呢
可以搜到
libcore/luni/src/main/native/libcore_io_Linux.cpp NATIVE_METHOD(Linux, getifaddrs, ()[Landroid/system/StructIfaddrs;),
这个跟上面的不一样看不出来对应的方法
原来NATIVE_METHOD是个宏
在libnativehelper/include/nativehelper/JniConstants.h
里有 82#define NATIVE_METHOD(className, functionName, signature) \
83 { #functionName, signature, reinterpret_castvoid*(className ## _ ## functionName) }
这个宏里进行了字符串拼接展开这个宏
{ getifaddrs, ()[Landroid/system/StructIfaddrs;, reinterpret_castvoid*(Linux_getifaddrs) } 所以是Linux_getifaddrs方法
1517static jobjectArray Linux_getifaddrs(JNIEnv* env, jobject) {
1518 static jmethodID ctor env-GetMethodID(JniConstants::structIfaddrs, init,
1519 (Ljava/lang/String;ILjava/net/InetAddress;Ljava/net/InetAddress;Ljava/net/InetAddress;[B)V);
1520 if (ctor NULL) {
1521 return NULL;