關於NDK想必大家都瞭解一點如
靜態註冊
//動態註冊
public native void registerJava01(String text);
這是一個最基本的Native
函數
那麼我們之前採用的靜態註冊就是在c/c++文件中填寫
extern "C"
JNIEXPORT void JNICALL
Java_com_example_myndk_MainActivity_registerJava01(){}
那麼這就是一種靜態註冊,也就是名字是組合得來的,但是當我們看有些源碼的時候我們發現並不是這樣的,其實他們就採用了靜態註冊的方法來註冊的。
動態註冊
所謂的動態註冊就是不需要一個方法名一個方法名的形式去寫,只需要寫一個就行,開始吧:
動態註冊需要實現這個方法
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM * javaVm,void * pVoid){}
怎麼理解這個方法呢,可以想成Aactivity中的onCreate這個方法,當
MainActivity
一加載的時候,就會調用這個方法。
//虛擬機
JavaVM * jvm;
void register01(JNIEnv *env,jobject instance,jstring text)
{
const char* textValue = env->GetStringUTFChars(text,NULL);
__android_log_print(ANDROID_LOG_DEBUG,"hongbiao","動態註冊的函數:%s",textValue);
env->ReleaseStringUTFChars(text,textValue);
}
//因爲註冊的那個方法需要這個結構體,所以需要創建
/**
* typedef struct {
const char* name; 對應java中的方法名
const char* signature; 編碼描述
void* fnPtr;可以理解爲接受的函數,數據將會傳到這個函數裏面來
} JNINativeMethod;
*/
RegisterNatives static const JNINativeMethod jniNativeMethod[] =
{
//這是一個數組,將需要進行動態註冊方法放到這裏面來
{"registerJava01","(Ljava/lang/String;)V",(void *)(register01)}
};
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM * javaVm,void * pVoid){
::jvm = javaVm;
JNIEnv* jniEnv = nullptr;
//通過虛擬機,創建全新的evn
jint result = javaVm->GetEnv(reinterpret_cast<void **>(&jniEnv),
JNI_VERSION_1_6);
if(result!=JNI_OK){
return -1;
}
const char * mainActivityClassStr = "com/example/myndk/MainActivity";
jclass mainActivity = jniEnv->FindClass(mainActivityClassStr);
//在哪裏動態註冊
jniEnv->RegisterNatives(mainActivity,
jniNativeMethod,
//下面兩個主要是進行個數的計算
sizeof(jniNativeMethod)/ sizeof(JNINativeMethod));
return JNI_VERSION_1_6;
}
其實動態註冊就是上面描述的這樣