日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

android源码分析之JNI调用与回调

發布時間:2025/3/15 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android源码分析之JNI调用与回调 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
通過JNI,Java程序可以在加載本地庫之后,調用Java類中聲明的在本地庫中實現的本地方法。此外,本地庫中的函數也可以通過回調的方式調用Java類中的成員變量或者成員函數。
? ? ? ?1、在Java中,本地庫的加載以及本地方法的聲明 public class Natvie{ //本地方法聲明 public native void nativeInit(); public native void nativeStart(); public native?boolean?nativeLoop(int?ptr); //本地庫加載 static { ?System.LoadLibrary("native"); }? }
2、在Native層的C文件中,需要進行本地方法的實現,以及方法綁定。
#include"jni.h" void nativeInit(JNIEnv*?env,?jclass?clazz){ ? ? ? ? ? ? ? ? //方法體實現 ? ? ? ? } ? ? ? ? //將Java類中的方法與本地方法名字進行綁定,即寫入JNINativeMethod數組中 ? ? ? ??static?JNINativeMethod?gTestMethods[] = { ? ? ? ? ? ? ? ? ? ? {"nativeInit",//Java類中的方法名 ? ? ? ? ? ? //方法參數,有Java中的全路徑類名,以及上下文等等 "(Lcom/android/server/test/TestService;Landroid/content/Context;Landroid/os/MessageQueue;)I", ? ? ? ? ? ? (void*)?nativeInit},//C++中的方法名 ? ? ? ? ? ? ? ? ? ? {"nativeStart", "(Lcom/android/server/test/TestService;Landroid/content/Context;Landroid/os/MessageQueue;)I", ? ? ? ? ? ? (void*)?nativeStart}, ? ? ? ? ? ? ? ? ? ? {...}, ? ? ? ? }
3、在Native中獲取Java類的回調,即在C++中調用Java的成員變量或成員方法。 在Java類中聲明: public void?onNativeCallback(int count){ Log.d("Natvie","onNativeCallback count="+count); } 在C++或C文件中聲明回調: static?struct?{ jmethodID?onNativeCallback; ... }?gServiceClassInfo;
在C++或C文件中進行回調獲取: 1) 獲取Java類 ? ? ? ? ? ? #define?FIND_CLASS(var,?className)?\ var?=?env->FindClass(className);?\ LOG_FATAL_IF(!?var,?"Unable?to?find?class?"?className);
2)獲取Java成員方法 #define?GET_METHOD_ID(var,?clazz,?methodName,?methodDescriptor)?\ var?=?env->GetMethodID(clazz,?methodName,?methodDescriptor);?\ LOG_FATAL_IF(!?var,?"Unable?to?find?method?"?methodName);
3)獲取Java成員變量 #define?GET_FIELD_ID(var,?clazz,?fieldName,?fieldDescriptor)?\ var?=?env->GetFieldID(clazz,?fieldName,?fieldDescriptor);?\ LOG_FATAL_IF(!?var,?"Unable?to?find?field?"?fieldName);
? ? ? ? 4、將JNINativeMethod以及回調函數等等注冊到JNI_OnLoad()中去。
int?register_android_server_Test(JNIEnv*?env)?{ int?res?=?jniRegisterNativeMethods(env,?"com/android/server/test/TestService", gTestMethods,?NELEM(gTestMethods)); LOG_FATAL_IF(res?<?0,?"Unable?to?register?native?methods.");
//?Callbacks
jclass?clazz; FIND_CLASS(clazz,?"com/android/server/test/TestService");
GET_METHOD_ID(gServiceClassInfo.onNativeCallback,?clazz, "onNativeCallback",?"(J)V");
return 0; }
此方法將gTestMethods數組,并綁定gServiceClassInfo中的回調函數,最后會在JNI_OnLoad()方法中將會調用 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? register_android_server_Test(env)方法,這里由于是自定義JNI,所以會在C++類中定義extern方法JNI_OnLoad(),并調用register_android_server_Test,但如果是framework/base/service下面的服務,則不需定義JNI_OnLoad()方法,但是它會在OnLoad.cpp中的JNI_OnLoad()方法中調用此服務中定義的類似于register_android_server_Test()的方法。 它會在Dalvik虛擬機啟動時,通過調用Dalvik_java_lang_Runtime_nativeLoad()->dvmLoadNativeCode()->vonLoad?=?dlsym(handle,?"JNI_OnLoad");將相應的JNI方法加載。
? ? ? ? 5、JNI庫加載過程
時序圖如下: 原文地址:http://blog.csdn.net/yangzhihuiguming/article/details/51274191

總結

以上是生活随笔為你收集整理的android源码分析之JNI调用与回调的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。