網(wǎng)絡(luò)上根本沒人說這么個玩意, ?包括一些寫書的老怪物.甚至他們的寫法都是非線程安全的。JAVA調(diào)用C++有2種方式,第一種很累需要把函數(shù)寫成JAVA規(guī)定的格式,第二種很繞,需要讓JAVA事先主動調(diào)用C++,C++根據(jù)他傳遞過來的類指針來操作?,F(xiàn)在說的是不需要對應(yīng)安卓類名直接注冊的機制,關(guān)鍵是QT能用。因為Qt中無法用JNI_OnLoad,因此我說的這個東西很重要。Qt中的新類:QtAndtoid提供了在JAVA UI線程環(huán)境中執(zhí)行C++代碼的功能:runOnAndroidThreadSync。
示例:JAVA中按返回鍵通知QT ?OnESCdown函數(shù)將由C++注冊給java調(diào)用
?public??native?void?OnESCdown(); ????????@Override ????????public?boolean?onKeyDown(int?keyCode,?KeyEvent?event) ????????{ ????????????OnESCdown();//通知C++層的?onEscDown函數(shù) ????????????Log.i("mod:","keycode:"+keyCode);?? ????????????if?(QtApplication.m_delegateObject?!=?null?&&?QtApplication.onKeyDown?!=?null) ????????????????return?(Boolean)?QtApplication.invokeDelegateMethod(QtApplication.onKeyDown,?keyCode,?event); ????????????else ????????????????return?super.onKeyDown(keyCode,?event); ????????}
C++:
static?void??onEscDown() { ????????qDebug()<<"C++?onEscDown"; } st atic?const?JNINativeMethod?gMethods[]?=?{?//定義批量注冊的數(shù)組,是注冊的關(guān)鍵部分 ????????????????????????????????????????????{?"OnESCdown",?"()V",?(void*)onEscDown?}?//?func2是在java中聲明的native函數(shù)名,"()V"是函數(shù)的簽名,可以通過javah獲取。 ??????????????????????????????????????????}; void??RegJni() { ????QtAndroid::runOnAndroidThreadSync([=](){ ???????????QAndroidJniEnvironment?EV; ???????????qDebug()<<"RegisterNatives???0***********"; ???????????qDebug()<<"RegisterNatives???1***********"; ???????????const?char*?kClassName?="org/qtproject/qt5/android/bindings/QtActivity"; ???????????jclass?clazz; ??????????clazz?=EV->FindClass(kClassName); ??????????if?(clazz?==?NULL) ??????????{ ??????????????qDebug()<<"erro???clazz"; ??????????????return?; ??????????} ??????????qDebug()<<"RegisterNatives???2***********"; ??????????if?(EV->RegisterNatives(clazz,?gMethods,?sizeof(gMethods)?/?sizeof(gMethods[0]))?!=?JNI_OK) ??????????{ ??????????????printf("register?native?method?failed!n"); ??????????????return; ??????????}else{ ??????????????qDebug()<<"RegisterNatives???搞定***********"; ??????????} ????}); ????//這里可以找到要注冊的類,前提是這個類已經(jīng)加載到j(luò)ava虛擬機中。?這里說明,動態(tài)庫和有native方法的類之間,沒有任何對應(yīng)關(guān)系。 ????//????QAndroidJniObject?javaClass(kClassName); ????//????????clazz?=?env->GetObjectClass(javaClass.object()); ????//????????qDebug()?<<"find?ExtendsQtNative"<<?clazz; ????EV->DeleteLocalRef(clazz);//刪除引用避免內(nèi)存泄漏 ????qDebug()<<"RegisterNatives???OK***********"; }