AndroidStudio下JNI開發(easy+1.0)之Java對象的傳遞與修改

概述

本文主要Java與C++之間的對象傳遞與取值。包括傳遞Java對象、返回Java對象、修改Java對象、以及性能對比。

通過JNIEnv完成數據轉換

Java對象是存在於JVM虛擬機中的,而C++是脫離JVM而運行的,如果在C++中訪問和使用Java中的對象,必然會使用JNIEnv這個橋樑。其實通過下面的代碼很容易看出,這種訪問方式和Java中的反射十分雷同。

這裏定義一個簡單Java對象用於下文測試:

<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">package</span> com.example.wastrel.hellojni;
<span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
 * Created by wastrel on 2016/8/24.
 */</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">Bean</span> {</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> String msg;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> what;

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">Bean</span>(String msg,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> what)
    {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.msg=msg;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.what=what;
    }


    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> String <span class="hljs-title" style="box-sizing: border-box;">getMsg</span>() {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> msg;
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">setMsg</span>(String msg) {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.msg = msg;
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> <span class="hljs-title" style="box-sizing: border-box;">getWhat</span>() {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> what;
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">setWhat</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> what) {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.what = what;
    }

    <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> String <span class="hljs-title" style="box-sizing: border-box;">toString</span>() {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Msg:"</span>+msg+<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">";What:"</span>+what;
    }
}
</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li></ul>

從C++中創建一個Java對象並返回

<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//Java中的native方法聲明</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">native</span> Bean <span class="hljs-title" style="box-sizing: border-box;">newBean</span>(String msg,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> what);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>
<code class="language-C++ hljs scala has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//C++中的方法實現</span>
JNIEXPORT j<span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">JNICALL</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">Java_com_example_wastrel_hellojni_HelloJNI_newBean</span></span>
        (JNIEnv *env, j<span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">obj</span>, <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">jstring</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">msg</span>,<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">jint</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">what</span>){</span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//先找到class</span>
    j<span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">bean_clz</span>=<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">env</span>-><span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">FindClass</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"com/example/wastrel/hellojni/Bean"</span>)</span>;</span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//在實際應用中應該確保你的class、method、field存在。減少此類判斷。</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(bean_clz==NULL)
    {
        LOGE(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"can't find class"</span>);
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> NULL;
    }
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//獲取構造函數。構造函數的返回值是void,因此這裏方法簽名最後爲V</span>
    jmethodID bean_init=env->GetMethodID(bean_clz,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"<init>"</span>,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"(Ljava/lang/String;I)V"</span>);
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(bean_init==NULL)
    {
        LOGE(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"can't find init function"</span>);
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> NULL;
    }
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//然後調用構造函數獲得bean</span>
    j<span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">bean</span>=<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">env</span>-><span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">NewObject</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(bean_clz,bean_init,msg,what)</span>;</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> bean;
}
</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li></ul>

注:如果提示找不到NULL 請include<stddef.h>

C++中解析Java對象

<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//java方法Native聲明</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">native</span> String <span class="hljs-title" style="box-sizing: border-box;">getString</span>(Bean bean);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>
<code class="language-c++ hljs mel has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//C++中的方法實現</span>
JNIEXPORT jstring JNICALL Java_com_example_wastrel_hellojni_HelloJNI_getString
        (JNIEnv <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">*env</span>, jobject obj,jobject bean){
    jclass bean_clz=<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">env</span>->FindClass(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"com/example/wastrel/hellojni/Bean"</span>);

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//這部分是通過get函數去獲取對應的值 </span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//    jmethodID bean_getmsg=env->GetMethodID(bean_clz,"getMsg","()Ljava/lang/String;");</span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//    jmethodID bean_getwhat=env->GetMethodID(bean_clz,"getWhat","()I");</span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//    jstring jmsg=(jstring)env->CallObjectMethod(bean,bean_getmsg);</span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//    jint what=env->CallIntMethod(bean,bean_getwhat);</span>

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//這部分是通過類的成員變量直接取獲取值,你可能注意到在Java中定義的變量都是private修飾的,但在反射的調用下是毫無作用的。</span>
    jfieldID bean_fmsg=<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">env</span>->GetFieldID(bean_clz,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"msg"</span>,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Ljava/lang/String;"</span>);
    jfieldID bean_fwhat=<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">env</span>->GetFieldID(bean_clz,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"what"</span>,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"I"</span>);
    jstring jmsg=(jstring)<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">env</span>->GetObjectField(bean,bean_fmsg);
    jint  what=<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">env</span>->GetIntField(bean,bean_fwhat);

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//將拿到的值拼裝一個String返回回去</span>
    const char * msg=<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">env</span>->GetStringUTFChars(jmsg,NULL);
    char <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">*str</span>=new char[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1024</span>];
    sprintf(str,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Msg:%s;What:%d(From C++)"</span>,msg,what);
    jstring rs=<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">env</span>->NewStringUTF(str);
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">delete</span>  []str;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">env</span>->ReleaseStringUTFChars(jmsg,msg);
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> rs;
}
</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li></ul>

注:sprintf函數包含在stdio.h頭文件中

C++中修改Java對象屬性值

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//java方法Native聲明</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">native</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">ModifyBean</span>(Bean bean);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>
<code class="hljs lasso has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//C++實現</span>
JNIEXPORT <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">void</span> JNICALL Java_com_example_wastrel_hellojni_HelloJNI_ModifyBean
        (JNIEnv <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">*</span>env, jobject obj,jobject bean){
    jclass bean_clz<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span>env<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>FindClass(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"com/example/wastrel/hellojni/Bean"</span>);
    jfieldID bean_fmsg<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span>env<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>GetFieldID(bean_clz,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"msg"</span>,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Ljava/lang/String;"</span>);
    jfieldID bean_fwhat<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span>env<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>GetFieldID(bean_clz,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"what"</span>,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"I"</span>);
    jstring msg<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span>env<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>NewStringUTF(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Modify in C++"</span>);
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//重新設置屬性</span>
    env<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>SetObjectField(bean,bean_fmsg,msg);
    env<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>SetIntField(bean,bean_fwhat,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">20</span>);
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>;
}
</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li></ul>

結果圖

<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//java中調用代碼</span>
        HelloJNI helloJNI=<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> HelloJNI();
        Bean bean=helloJNI.newBean(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"This is from C++ bean"</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>);
        tv.setText(bean.toString());
        bean=<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Bean(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"This is from Java bean"</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">15</span>);
        tv.append(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"\n"</span>+helloJNI.getString(bean));
        helloJNI.ModifyBean(bean);
        tv.append(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"\n"</span>+bean.toString());</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li></ul>

這裏寫圖片描述

Java中new Object和C++中new Object的性能對比

下面我們通過一個測試函數來比較通過兩種方式的性能,這裏可以毫無疑問的告訴你,Java一定比C++的快。那麼這個對比的意義就在於,使用C++創建Java對象的時候會不會造成不可接受的卡頓。 
這裏使用的測試機是華爲Mate7,具體硬件配置可自行百度。 
測試函數如下:

<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">     <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> Test(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> count)
    {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">long</span> startTime=System.currentTimeMillis();
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;i<count;i++)
        {
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Bean(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"123"</span>,i);
        }
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">long</span> endTime=System.currentTimeMillis();
        Log.e(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Java"</span>,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Java new "</span>+count+<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"s waste "</span>+(endTime-startTime)+<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"ms"</span>);

        HelloJNI helloJNI=<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> HelloJNI();
       startTime=System.currentTimeMillis();
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;i<count;i++)
        {
            helloJNI.newBean(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"123"</span>,i);
        }
        endTime=System.currentTimeMillis();
        Log.e(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"C++"</span>,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"C++ new "</span>+count+<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"s waste "</span>+(endTime-startTime)+<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"ms"</span>);
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li></ul>

測試結果:

<code class="hljs http has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-attribute" style="box-sizing: border-box;">Java</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">Java new 5000s waste 3ms</span>
<span class="hljs-attribute" style="box-sizing: border-box;">C++</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">C++ new 5000s waste 38ms</span>

<span class="http" style="box-sizing: border-box;"><span class="hljs-attribute" style="box-sizing: border-box;">Java</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">Java new 10000s waste 6ms</span>
<span class="hljs-attribute" style="box-sizing: border-box;">C++</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">C++ new 10000s waste 79ms</span>

<span class="http" style="box-sizing: border-box;"><span class="hljs-attribute" style="box-sizing: border-box;">Java</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">Java new 50000s waste 56ms</span>
<span class="hljs-attribute" style="box-sizing: border-box;">C++</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">C++ new 50000s waste 338ms</span>

<span class="http" style="box-sizing: border-box;"><span class="hljs-attribute" style="box-sizing: border-box;">Java</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">Java new 100000s waste 60ms</span>
<span class="hljs-attribute" style="box-sizing: border-box;">C++</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">C++ new 100000s waste 687ms</span></span></span></span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li></ul>

通過結果可以看出,通過C++來new對象比Java慢了足足10倍左右。但是從時間上來講,如果只是在C++中new一個Java對象,幾個微秒的時間差距完全是可以忽略不計的。

也許有人就會說,C++慢那麼多是因爲每次都在FindClass,GetMethodId,而在程序運行過程中這兩個值是不會改變的。聽起來確實有這樣一個原因,下面我們將C++中的代碼稍作修改緩存jclass和jmethodId。 
修改後的newBean函數:

<code class="language-C++ hljs scala has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//用靜態變量緩存</span>
static j<span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">bean_clz</span>=<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">NULL</span>;</span>
static jmethodID bean_init=NULL;
JNIEXPORT j<span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">JNICALL</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">Java_com_example_wastrel_hellojni_HelloJNI_newBean</span></span>
        (JNIEnv *env, j<span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">obj</span>, <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">jstring</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">str</span>,<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">jint</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">what</span>){</span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//先找到class</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(bean_clz==NULL)
    {
        j<span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span>  <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">_bean_clz</span>=<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">env</span>-><span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">FindClass</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"com/example/wastrel/hellojni/Bean"</span>)</span>;</span>
        bean_clz=(jclass)env->NewGlobalRef(_bean_clz);
    }
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//獲取構造函數。構造函數的返回值是void,因此這裏方法簽名最後爲V</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(bean_init==NULL)
    {
        bean_init=env->GetMethodID(bean_clz,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"<init>"</span>,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"(Ljava/lang/String;I)V"</span>);
    }
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//然後調用構造函數獲得bean</span>
    j<span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">bean</span>=<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">env</span>-><span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">NewObject</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(bean_clz,bean_init,str,what)</span>;</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> bean;
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li></ul>

 你可能發現了緩存方法ID和緩存jclass似乎不一樣。那是因爲jclass其實是java.lang.Class對象,而方法ID是JNI中定義的一個結構體。如果這裏不使用env—>NewGlobalRef()函數聲明其是一個全局引用的話,在運行的時候可能就會報錯:JNI ERROR (app bug): accessed stale local reference 0x5900021;表明在Jvm中該對象已經被回收了,引用已經失效了。而NewGlobalRef的作用就在於告訴JVM,C++中一直持有該引用,請不要回收。顯然這又引發了另外一個問題,你需要在你不需要該引用的時候告訴JVM,那麼就需要調用env->DelGlobalRef()。當然你也可以不調用,那麼該Java對象將在你的程序關閉的時候被回收。

測試結果:

<code class="hljs http has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-attribute" style="box-sizing: border-box;">Java</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">Java new 5000s waste 3ms</span>
<span class="hljs-attribute" style="box-sizing: border-box;">C++</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">C++ new 5000s waste 18ms</span>

<span class="http" style="box-sizing: border-box;"><span class="hljs-attribute" style="box-sizing: border-box;">Java</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">Java new 10000s waste 5ms</span>
<span class="hljs-attribute" style="box-sizing: border-box;">C++</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">C++ new 10000s waste 24ms</span>

<span class="http" style="box-sizing: border-box;"><span class="hljs-attribute" style="box-sizing: border-box;">Java</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">Java new 50000s waste 44ms</span>
<span class="hljs-attribute" style="box-sizing: border-box;">C++</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">C++ new 50000s waste 121ms</span>

<span class="http" style="box-sizing: border-box;"><span class="hljs-attribute" style="box-sizing: border-box;">Java</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">Java new 100000s waste 65ms</span>
<span class="hljs-attribute" style="box-sizing: border-box;">C++</span>: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">C++ new 100000s waste 259ms</span></span></span></span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li></ul>

這次的結果表明,如果緩存方法ID和jclass能縮短一半的時間。但仍然不如Java快。這也很好理解,C++創建Java對象最終還是通過Java創建的,反覆的通過反射去創建自然不如自身創建來得快。

總結

  • JNI中想訪問Java Object方法簽名、類名和變量名十分重要,一旦確定了就不要輕易單方面修改Java中的定義。因爲這會導致JNI找不到相關的方法或類等,而引發JNI錯誤。
  • 雖然JNI提供了各種方法來完成Java的反射操作,但是請酌情使用,因爲這會讓Java代碼與C++代碼之間過度依賴。
  • 當你需要返回C++中的結構體數據的時候,可以考慮把結構體轉換成對應的Java對象返回。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章