解決在android平臺上apk的覆蓋安裝so檔案不覆蓋問題
阿新 • • 發佈:2019-01-25
過程:
在網上搜索android上需要手動清除資料/手動解除安裝的原因及解決方法,發現根本找不到這方面的資料。
反思:
在一個開源平臺上,別人都不會碰到同樣的問題嗎?只能說明一個問題,這個問題,要麼太深奧,要麼太簡單。我想到了自從一開始就一直縈繞在我心頭的一個初始化函式的實現:JNI_OnLoad
解決:
又一次詳細地看了JNI_OnLoad這個函式可能帶來的好處:初始化,定義最低JNI版本,註冊方法。 抱著試試看的心態,試著寫這個函式,夢想著能夠解決問題。
結果,大功告成!^_^
小結:
(1)這次dms/dmr/dmc三個JNI檔案中的native方法很多,工作量不小,但是效率卻比較高。我想這是平時積累見到的成效。
(2) 關於獲取env及規定最低版本,以前嘗試寫在JNI_OnLoad裡,但是出錯,但是現在卻對了;直接獲取類的ID的方法FindClass,以前沒有JNI_OnLoad方法的時候,將它用在nativesetup方法裡,出錯,在nativesetup方法裡,就只能用FindObjectClass可用了。以前不能用,現在可用,應該是某個地方細微的差別導致的。如果學藝不精,解決問題會很浪費時間,什麼都要查資料。累積的知識到了一定的程度,即便碰到問題,也能很快找出原因並解決。
(3)在開發過程中碰到方法註冊失敗的問題。如果Java檔案裡沒有相應的native方法,在底層介面中最好將其註釋掉,免得導致註冊失敗。這個問題的解決關鍵,在於從C++程式碼跳到Java程式碼來解決問題的思路。
現在貼上部分程式碼,以備留念。
程式碼:
<pre name="code" class="cpp">//methods table static JNINativeMethod gMethods[] = { {"A", "(Ljava/lang/Object;)V", (void *)Java_com_hr_renderer_dmr_A}, {"B", "(Ljava/lang/String;)I", (void *)Java_com_hr_renderer_dmr_B}, {"C", "(Ljava/lang/String;)I", (void *)Java_com_hr_renderer_dmr_C}, {"D", "()I", (void *)Java_com_hr_renderer_dmr_D}, {"E", "()Ljava/lang/String;", (void *)Java_com_hr_renderer_dmr_E}, {"F", "()Ljava/lang/String;", (void *)Java_com_hr_renderer_dmr_F}, {"G", "(Ljava/lang/String;Ljava/lang/String;)V", (void *)Java_com_hr_renderer_dmr_G}, {"H", "(Ljava/lang/String;)I", (void *)Java_com_hr_renderer_dmr_H}, {"I", "(Ljava/lang/String;)Ljava/lang/String;", (void *)Java_com_hr_renderer_dmr_I}, {"J", "()Z", (void *)Java_com_hr_renderer_dmr_J}, }; /* define the minimum version * initialization * register native methods. * */ jint JNI_OnLoad(JavaVM* vm, void* reserved) { NPT_LogManager::GetDefault().Configure("plist:.level=INFO;.handlers=ConsoleHandler;.ConsoleHandler.colors=off;.ConsoleHandler.filter=42"); JNIEnv* env = NULL; jint result = -1; if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) { NPT_LOG_INFO("JNI version error!"); return result; } //assert(env != NULL); if (env == NULL) { NPT_LOG_INFO("JNI-----getEnv fail."); return result; } //gJavaVM env->GetJavaVM(&gJavaVM); if (env->ExceptionOccurred()) { NPT_LOG_INFO("JNI-----GetJavaVM fail."); return result; } clazz = env->FindClass(classPathName); if (clazz == NULL) { NPT_LOG_INFO_1("JNI Cannot find %s!", classPathName); return result; } //get MethodID postEventMethodID = env->GetStaticMethodID(clazz, "postEvent", "(Ljava/lang/Object;ILjava/lang/String;Ljava/lang/String;)V"); //if ExceptionOccurred if (env->ExceptionOccurred()) { NPT_LOG_INFO("JNI-----GetStaticMethodID fail."); return result; } //register methods. if (env->RegisterNatives(clazz, gMethods, sizeof(gMethods)/sizeof(gMethods[0])) < 0) { NPT_LOG_INFO("JNI-----RegisterNatives fail."); return result; } NPT_LOG_INFO("JNI_OnLoad-----sucess!"); return JNI_VERSION_1_4; } /* UnregisterNatives */ void JNI_OnUnload(JavaVM* vm, void* reserved) { JNIEnv* env = NULL; if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) { NPT_LOG_INFO("JNI UnregisterNatives: get env fail"); return; } else { NPT_LOG_INFO("JNI_OnUnload Unregister!"); env-> UnregisterNatives(clazz); return; } }
注意:以上是原博主的原文,本人還沒有嘗試,故不太懂,懂得童鞋可以一試。