1. 程式人生 > >解決在android平臺上apk的覆蓋安裝so檔案不覆蓋問題

解決在android平臺上apk的覆蓋安裝so檔案不覆蓋問題

過程:

在網上搜索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;  
    }      
}  

注意:以上是原博主的原文,本人還沒有嘗試,故不太懂,懂得童鞋可以一試。