背景:

一步步摸索着开发走来,本着能走通就继续往前走的原则,将dlna项目做到了现在,做到了出产品。

可是一直有一个问题困扰着我,为什么我们的程序不能覆盖安装?其他的android应用程序,无论带不带动态库,都可以实现覆盖安装,不用很麻烦地一步步进行手动清除数据/手动卸载/然后才能安装的问题。否则,如果直接安装,可能会导致so包更新失败的问题,会继续使用旧的so包。更搞笑的是,即便把某个so包删除,程序也不会报错,即便用到了该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代码来解决问题的思路。


做开发,多积累,准没错,它的成效会比你想象的还要好。

现在贴上部分代码,以备留念。

代码:



[cpp] view plain copy print ?


    1. <code class="language-cpp">//methods table   
    2. static
    3. "A",    "(Ljava/lang/Object;)V",  (void
    4. "B",    "(Ljava/lang/String;)I",  (void
    5. "C",   "(Ljava/lang/String;)I",  (void
    6. "D",    "()I",  (void
    7. "E",    "()Ljava/lang/String;",  (void
    8. "F",    "()Ljava/lang/String;",  (void
    9. "G",    "(Ljava/lang/String;Ljava/lang/String;)V",  (void
    10. "H",    "(Ljava/lang/String;)I",  (void
    11. "I",    "(Ljava/lang/String;)Ljava/lang/String;",  (void
    12. "J",    "()Z",  (void
    13. };  
    14.     
    15. /*  define the minimum version 
    16.  *  initialization
    17.  *  register native methods. 
    18.  * */
    19. jint JNI_OnLoad(JavaVM* vm, void* reserved)  
    20. {  
    21. "plist:.level=INFO;.handlers=ConsoleHandler;.ConsoleHandler.colors=off;.ConsoleHandler.filter=42");  
    22.     JNIEnv* env = NULL;  
    23.     jint result = -1;  
    24. if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK)    
    25.     {  
    26. "JNI version error!");  
    27. return
    28.     }  
    29. //assert(env != NULL);
    30. if
    31.     {  
    32. "JNI-----getEnv fail.");  
    33. return
    34.     }  
    35.   
    36. //gJavaVM
    37.     env->GetJavaVM(&gJavaVM);  
    38. if
    39.     {  
    40. "JNI-----GetJavaVM fail.");  
    41. return
    42.     }  
    43.   
    44.     clazz = env->FindClass(classPathName);  
    45. if
    46.     {  
    47. "JNI Cannot find %s!", classPathName);  
    48. return
    49.     }  
    50.       
    51. //get MethodID
    52. "postEvent", "(Ljava/lang/Object;ILjava/lang/String;Ljava/lang/String;)V");  
    53.      
    54. //if ExceptionOccurred
    55. if
    56.     {  
    57. "JNI-----GetStaticMethodID fail.");  
    58. return
    59.     }  
    60.      
    61. //register methods.
    62. if (env->RegisterNatives(clazz, gMethods, sizeof(gMethods)/sizeof(gMethods[0])) < 0)   
    63.     {  
    64. "JNI-----RegisterNatives fail.");  
    65. return
    66.     }  
    67. "JNI_OnLoad-----sucess!");  
    68. return
    69.   
    70. }  
    71.   
    72. /* UnregisterNatives  */
    73. void JNI_OnUnload(JavaVM* vm, void* reserved)  
    74. {  
    75.     JNIEnv* env = NULL;  
    76. if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK)    
    77.     {  
    78. "JNI UnregisterNatives: get env fail");  
    79. return;  
    80.     }  
    81. else
    82.     {  
    83. "JNI_OnUnload Unregister!");  
    84.         env-> UnregisterNatives(clazz);  
    85. return;  
    86.     }      
    87. }  
    88. </code>


    //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; }    }
    //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; }    }