android的JNI开发一种是内核级的(android源码),一种是一般的应用程序(它被打入到APK包)。在此讨论的是一般的应用程序。
开发JNI应用需要的工具有
<wbr style="line-height:25px">AndroidNDK</wbr><wbr style="line-height:25px"><br style="line-height:25px"> 下载地址:<br style="line-height:25px"><wbr style="line-height:25px"><span style="color:#3366ff; line-height:25px">http://developer.android.com/sdk/ndk/index.html#requirements</span> <div style="line-height:25px"> <span style="line-height:25px"><wbr style="line-height:25px">而要运行AndroidNDK的命令(比如ndk-build)需要</wbr></span><wbr style="line-height:25px">:<br style="line-height:25px"><span style="color:#0000ff; line-height:25px">*Foralldevelopmentplatforms,</span><span style="color:#ff6600; line-height:25px">GNUMake3.81orlater</span><span style="color:#0000ff; line-height:25px">isrequired.EarlierversionsofGNUMakemightworkbuthavenotbeentested<br style="line-height:25px"> *Arecentversionof</span><span style="color:#ff6600; line-height:25px">awk(eitherGNUAwkorNawk)</span><span style="color:#0000ff; line-height:25px">isalsorequired.<br style="line-height:25px"> *For</span><span style="color:#ff6600; line-height:25px">Windows</span><span style="color:#0000ff; line-height:25px">,</span><span style="color:#ff6600; line-height:25px"><span style="line-height:25px"><wbr style="line-height:25px">Cygwin1.7</wbr></span><wbr style="line-height:25px">orhigherisrequired</wbr></span><span style="color:#0000ff; line-height:25px">.TheNDKwillnotworkwithCygwin1.5installations.</span><br style="line-height:25px"> 以上信息来自于http://developer.android.com/sdk/ndk/index.html#requirements.<br style="line-height:25px"><span style="line-height:25px">注意</span>:<span style="color:#ff6600; line-height:25px"><wbr style="line-height:25px">Android的这个文档有点误导人<wbr style="line-height:25px">。</wbr></wbr></span><br style="line-height:25px"><span style="color:#000080; line-height:25px">对于Linux平台需要GNUMake3.81orlater,或Arecentversionofawk(eitherGNUAwkorNawk)。<br style="line-height:25px"> 虽然对于Windows也需要GNUMake3.81orlater,或Arecentversionofawk(eitherGNUAwkorNawk)。<br style="line-height:25px"> 但是实际上如果对</span><span style="color:#ff6600; line-height:25px">Cygwin1.7orhigher是完全安装的话</span>,<wbr style="line-height:25px"><span style="color:#ff6600; line-height:25px">Cygwin就已经包含了GNUMake和awk的window版本</span><span style="line-height:25px">。</span><br style="line-height:25px"><span style="color:#000080; line-height:25px">因此Window平台下,其实对Cygwin进行完全安装就行了<wbr style="line-height:25px">。<br style="line-height:25px"> 在http://developer.android.com/sdk/ndk/index.html#requirements还有很多有用信息,可以参阅。</wbr></span><br style="line-height:25px"><span style="line-height:25px">GNUMake下载地址</span><br style="line-height:25px"><span style="color:#000080; line-height:25px">linux版本</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">http://ftp.gnu.org/gnu/make/</span><br style="line-height:25px"><span style="line-height:25px">awk下载地址</span>:<br style="line-height:25px"><span style="color:#000080; line-height:25px">linux版本</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">http://linux.softpedia.com/get/Text-Editing-Processing/Filters/GNU-awk-207.shtml<br style="line-height:25px"></span><span style="color:#000080; line-height:25px">window版本</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">http://www.softpedia.com/get/CD-DVD-Tools/CD-DVD-Images-Utils/Gawk-for-Windows.shtml</span><br style="line-height:25px"><span style="line-height:25px">gawk下载地址</span>:<br style="line-height:25px"><span style="color:#3366ff; line-height:25px">http://ftp.gnu.org/gnu/gawk/</span><br style="line-height:25px"><span style="line-height:25px">Cygwin下载地址</span>。</wbr></wbr> </div> <div style="line-height:25px"> <span style="color:#3366ff; line-height:25px">http://www.cygwin.com/</span><br style="line-height:25px"><wbr style="line-height:25px">关于Cygwin安装步骤请参阅《<strong><a title="阅读全文" target="_blank" href="http://hubingforever.blog.163.com/blog/static/17104057920116641557558/" style="color:rgb(207,121,28); line-height:25px; text-decoration:none">cygwin安装详解</a></strong>》</wbr> </div> <div style="line-height:25px"> <span style="line-height:25px">注意</span>:<wbr style="line-height:25px">Cygwin的安装包选项那屏,点击包菜单根的"All"后面的"Default",然它变成"install",就是完全安装。</wbr> </div> <div style="line-height:25px"> <span style="color:#003366; line-height:25px">在安装AndroidNDK后:</span><br style="line-height:25px"><span style="color:#003366; line-height:25px">在其samples目录下找到很多实例程序</span><br style="line-height:25px"><span style="color:#003366; line-height:25px">在其docs目录下可以看到有很多帮助文档,</span><br style="line-height:25px"><span style="color:#000080; line-height:25px">首先阅读的应该是OVERVIEW.TXT。<br style="line-height:25px"> 关于Android.mk文件的编写在ANDROID-MK.TXT中<br style="line-height:25px"> 关于Application.mk文件的编写在APPLICATION-MK.TXT中<br style="line-height:25px"> 关于AndroidNDK的安装要求在INSTALL.TXT中。</span><br style="line-height:25px"> 如何在Eclipse中进行android的JNI开发。<br style="line-height:25px"><span style="line-height:25px"><wbr style="line-height:25px">1,首先需要在Eclipse建个Android工程</wbr></span><wbr style="line-height:25px">。<br style="line-height:25px"><span style="color:#000080; line-height:25px">工程名为JniHello,Activity名为HelloActivity</span><br style="line-height:25px"><span style="line-height:25px"><wbr style="line-height:25px">2,HelloActivity中载入一个JNI包</wbr></span><wbr style="line-height:25px">。<br style="line-height:25px"><span style="color:#000080; line-height:25px">在使用JNI的接口前,需要载入JIN的包。<br style="line-height:25px"> 我这里的JIN包名为hello-jni<br style="line-height:25px"> (其文件名为lib+包名+.so,即libhello-jni.so)。<br style="line-height:25px"> HelloActivity中载入如下:<br style="line-height:25px"> static{<br style="line-height:25px"> System.loadLibrary("hello-jni");<br style="line-height:25px"> }</span><br style="line-height:25px"> 3,<span style="line-height:25px"><wbr style="line-height:25px">在Java声明一个JNI函数</wbr></span><wbr style="line-height:25px">:<br style="line-height:25px"><span style="color:#000080; line-height:25px">nativeStringgetStringFromJni();</span><br style="line-height:25px"> 4,<span style="line-height:25px"><wbr style="line-height:25px">在Java中使用JIN函数和一般的java函数一样</wbr></span><wbr style="line-height:25px">。<br style="line-height:25px"><span style="color:#3366ff; line-height:25px">publicvoidonCreate(BundlesavedInstanceState){<br style="line-height:25px"> super.onCreate(savedInstanceState);<br style="line-height:25px"> setContentView(R.layout.main);<br style="line-height:25px"> TextViewtextView=(TextView)findViewById(R.id.textView1);<br style="line-height:25px"> textView.setText(</span><span style="color:#ff6600; line-height:25px">getStringFromJni())</span><span style="color:#3366ff; line-height:25px">;<br style="line-height:25px"> }</span><br style="line-height:25px"> 5,<span style="line-height:25px"><wbr style="line-height:25px">建立jni源代码的目录jni</wbr></span><wbr style="line-height:25px">.<br style="line-height:25px"> 在JniHello下建立个jni目录。</wbr></wbr></wbr></wbr></wbr> </div> <div style="line-height:25px"><span style="line-height:25px">6,在头文件中声明C\C++的Jni函数</span></div> <div style="line-height:25px"> <span style="line-height:25px; font-family:Arial,Helvetica,simsun,u5b8bu4f53"></span> <div style="line-height:22px"><span style="color:#003366; line-height:22px">如果你需要不同的JNI的C\C++实现文件的函数能互相调用,那么你就需要为你的JNI的C\C++端编写扩展名为h的头文件。</span></div> <div style="line-height:22px"><span style="color:#003366; line-height:22px">你可以手写头文件,也可以使用javah命令。</span></div> <div style="line-height:22px"> <span style="color:#003366; line-height:22px">关于javah命令的详细内容请参考《</span><strong><a title="阅读全文" target="_blank" href="http://hubingforever.blog.163.com/blog/static/17104057920115218559186/" style="color:rgb(207,121,28); line-height:22px; text-decoration:none">javah命令详解</a></strong><span style="line-height:22px; color:rgb(0,51,102)">》</span> </div> <div style="line-height:22px"><span style="line-height:22px; color:rgb(0,51,102)">这里我不需要不同的JNI的C\C++实现文件的函数进行调用,因此略去该步骤。</span></div> <span style="line-height:25px"><wbr style="line-height:25px">7,定义Jni函数</wbr></span><wbr style="line-height:25px">。</wbr> </div> <div style="line-height:25px"> <span style="color:#000080; line-height:25px">在目录jni下新建个文件hello-jni.c如下:<br style="line-height:25px"> #include<string.h><br style="line-height:25px"> #include<jni.h><br style="line-height:25px"></span><span style="color:#99cc00; line-height:25px"></span><span style="color:#ff9900; line-height:25px">jstring</span><br style="line-height:25px"><span style="color:#000080; line-height:25px"></span><span style="color:#ff9900; line-height:25px">Java</span><span style="color:#000080; line-height:25px">_</span><span style="color:#ff6600; line-height:25px">c</span><span style="color:#ff6600; line-height:25px">om_teleca_robin_HelloActivity</span><span style="color:#000080; line-height:25px">_</span><span style="color:#ff9900; line-height:25px">getStringFromJni</span><span style="color:#000080; line-height:25px">(JNIEnv*env,<br style="line-height:25px"> jobjectthiz)<br style="line-height:25px"> {<br style="line-height:25px"> return(*env)->NewStringUTF(env,"Hellorobin,thisworldisfromJNI!");<br style="line-height:25px"> }</span><span style="line-height:25px"><br style="line-height:25px"> 函数返回类型</span><br style="line-height:25px"><span style="color:#ff9900; line-height:25px">jstring</span><span style="color:#0000ff; line-height:25px">代表的是返回类型。这里应该表示的是java的String.</span><br style="line-height:25px"><span style="line-height:25px">函数名字</span><br style="line-height:25px"><span style="color:#0000ff; line-height:25px">函数名字首先是前缀java,然后是要调用该JNI的Java类的路径,</span><br style="line-height:25px"><span style="color:#0000ff; line-height:25px">接着是Java中申明的函数的名字</span>。<br style="line-height:25px"><span style="line-height:25px">函数参数</span><br style="line-height:25px"><span style="color:#0000ff; line-height:25px">第一个参数永远应该是JNIEnv*env,<br style="line-height:25px"> 第二个参数jobjectthiz是java中的this指针。<br style="line-height:25px"> 第三个参数开始是Java的函数中的参数。</span><br style="line-height:25px"><span style="color:#000080; line-height:25px">比如实例bitmap-plasma中的Plasma对renderPlasma声明如下:</span><br style="line-height:25px"><span style="color:#993300; line-height:25px">privatestaticnativevoid</span><span style="color:#0000ff; line-height:25px">renderPlasma(Bitmapbitmap,longtime_ms);</span><br style="line-height:25px"><span style="color:#000080; line-height:25px">在jni中则为</span><br style="line-height:25px"><span style="color:#0000ff; line-height:25px">JNIEXPORTvoidJNICALLJava_com_example_plasma_PlasmaView_renderPlasma(JNIEnv*env,jobjectobj,jobjectbitmap,jlongtime_ms)<br style="line-height:25px"></span> </div> <div style="line-height:25px"> <span style="color:#000080; line-height:25px">关于JNI中参数的传递与操作的更多内容请参考《</span><strong><a title="阅读全文" target="_blank" href="http://hubingforever.blog.163.com/blog/static/17104057920115712234774/" style="color:rgb(207,121,28); line-height:25px; text-decoration:none">JNI中参数的传递与操作</a></strong><span style="line-height:25px; color:rgb(0,0,128)">》</span> </div> <div style="line-height:25px"> <span style="line-height:25px">注意</span>:JNIEXPORT和JNICALL都是JNI的关键字,表示此函数是要被JNI调用的</div> <div style="line-height:25px"> <div style="line-height:25px"><span style="color:#000080; line-height:25px">应用层级的Java类别通过VM而调用到本地函数,VM默认是按照JNI的java函数和C\C++本地函数的命名规范,去寻找*.so里的本地函数。</span></div> <div style="line-height:25px"><span style="color:#000080; line-height:25px">查找的过程还是有点耗时。如果调用次数很多,而每次都寻找一遍的话,会花掉许多时间。</span></div> <div style="line-height:25px"><span style="color:#000080; line-height:25px">如果你想节约VM查找JNI本地函数的时间,你可以通过registerNativeMethods()函数把JNI本地函数向VM进行登记,以节约VM查找JNI本地函数的时间。</span></div> <div style="line-height:25px"><span style="color:#000080; line-height:25px">如果你的JNI本地函数的命名没严格遵守java函数和C\C++本地函数对应的命名规范,你必须通过registerNativeMethods()函数把JNI本地函数向VM进行登记,以便VM能找到你的JNI本地函数。</span></div> </div> <div style="line-height:25px">关于JNI本地函数向VM进行登记,请参照《<strong><a title="阅读全文" target="_blank" href="http://hubingforever.blog.163.com/blog/static/171040579201151835834200/" style="color:rgb(207,121,28); line-height:25px; text-decoration:none">JNI系统程序开发</a></strong>》</div> <div style="line-height:25px"><wbr style="line-height:25px"><span style="line-height:25px">8,编辑Android.mk</span><wbr style="line-height:25px"><br style="line-height:25px"><span style="color:#000080; line-height:25px">在jni下新建Android.mk文件如下:<br style="line-height:25px"> LOCAL_PATH:=$(callmy-dir)<br style="line-height:25px"> include$(CLEAR_VARS)<br style="line-height:25px"> LOCAL_MODULE:=hello-jni<br style="line-height:25px"> LOCAL_SRC_FILES:=hello-jni.c<br style="line-height:25px"></span><span style="color:#000080; line-height:25px">include$(BUILD_SHARED_LIBRARY)。</span></wbr></wbr></div> <div style="line-height:25px"> <span style="line-height:25px; font-family:Arial,Helvetica,simsun,u5b8bu4f53">关于<span style="line-height:22px">Android.mk的更多内容请参照《</span><strong><a title="阅读全文" target="_blank" href="http://hubingforever.blog.163.com/blog/static/171040579201152185542166/" style="color:rgb(207,121,28); line-height:22px; text-decoration:none">Android.mk</a></strong>》</span><span style="color:#000080; line-height:25px"><br style="line-height:25px"></span><span style="line-height:25px">9,编译JNI</span><wbr style="line-height:25px"><br style="line-height:25px"><span style="color:#000080; line-height:25px">在cygwin\home\hubin的.bash_profile文件中添加设置ndk的路径。</span><br style="line-height:25px"><span style="color:#000080; line-height:25px">NDK=/cygdrive/d/SDK/android-ndk-r4b</span><br style="line-height:25px"><span style="color:#000080; line-height:25px">exportNDK。</span><br style="line-height:25px"><span style="color:#000080; line-height:25px">programs->Cygwin->Cygwin Bash Shell或直接点击cygwin\Cygwin.bat打开cygwinbashshell窗口,</span><br style="line-height:25px"><span style="color:#000080; line-height:25px">然后进入工程JniHello的根目录</span><br style="line-height:25px"><span style="color:#ff6600; line-height:25px">执行$NDK/ndk-build。</span><br style="line-height:25px"><span style="color:#000080; line-height:25px">这时应该就能在JniHello的根目录的libs\armeabi下生成libhello-jni.so。</span><br style="line-height:25px"><span style="line-height:25px">注意</span><span style="color:#000080; line-height:25px">:在cygwin中进入一个盘符的命令为cdD:的形式</span></wbr> </div> <div style="line-height:25px">关于Cygwin的使用的更多内容请参阅《<strong><a title="阅读全文" target="_blank" href="http://hubingforever.blog.163.com/blog/static/171040579201161932655494/" style="color:rgb(207,121,28); line-height:25px; text-decoration:none">Cygwin使用指南</a></strong>》</div> <div style="line-height:25px"> <span style="line-height:25px">10,在Ecplise中重新打包生成apk文件,libhello-jni.so也同时被打进了apk</span><wbr style="line-height:25px">.<br style="line-height:25px"><span style="line-height:25px"><wbr style="line-height:25px">11,像运行一般android程序一样运行该程序</wbr></span><wbr style="line-height:25px">。<br style="line-height:25px"><span style="color:#000080; line-height:25px">在jni函数中向android的控制台打印信息可以采用以下的方式。<br style="line-height:25px"> #include<android/log.h><br style="line-height:25px"> #defineLOGI(...)__android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)<br style="line-height:25px"> #defineLOGE(...)__android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)<br style="line-height:25px"> LOGI("frame/s(avg,min,max)=(%.1f,%.1f,%.1f)"<br style="line-height:25px"> "rendertimems(avg,min,max)=(%.1f,%.1f,%.1f)\n",<br style="line-height:25px"> 1000./avgFrame,1000./maxFrame,1000./minFrame,<br style="line-height:25px"> avgRender,minRender,maxRender);</span><br style="line-height:25px"><wbr style="line-height:25px">关于如何定义多个JNI包(module),请参考android-ndk-r4b\samples\two-libs</wbr></wbr></wbr> </div> <div style="line-height:25px">关于jni的使用可以参照《<strong><a title="阅读全文" target="_blank" href="http://hubingforever.blog.163.com/blog/static/17104057920115992114907/" style="color:rgb(207,121,28); line-height:25px; text-decoration:none">JNI应用程序开发实例1</a></strong>》</div> </wbr></wbr>
开发JNI应用需要的工具有
<wbr style="line-height:25px">AndroidNDK</wbr><wbr style="line-height:25px"><br style="line-height:25px"> 下载地址:<br style="line-height:25px"><wbr style="line-height:25px"><span style="color:#3366ff; line-height:25px">http://developer.android.com/sdk/ndk/index.html#requirements</span> <div style="line-height:25px"> <span style="line-height:25px"><wbr style="line-height:25px">而要运行AndroidNDK的命令(比如ndk-build)需要</wbr></span><wbr style="line-height:25px">:<br style="line-height:25px"><span style="color:#0000ff; line-height:25px">*Foralldevelopmentplatforms,</span><span style="color:#ff6600; line-height:25px">GNUMake3.81orlater</span><span style="color:#0000ff; line-height:25px">isrequired.EarlierversionsofGNUMakemightworkbuthavenotbeentested<br style="line-height:25px"> *Arecentversionof</span><span style="color:#ff6600; line-height:25px">awk(eitherGNUAwkorNawk)</span><span style="color:#0000ff; line-height:25px">isalsorequired.<br style="line-height:25px"> *For</span><span style="color:#ff6600; line-height:25px">Windows</span><span style="color:#0000ff; line-height:25px">,</span><span style="color:#ff6600; line-height:25px"><span style="line-height:25px"><wbr style="line-height:25px">Cygwin1.7</wbr></span><wbr style="line-height:25px">orhigherisrequired</wbr></span><span style="color:#0000ff; line-height:25px">.TheNDKwillnotworkwithCygwin1.5installations.</span><br style="line-height:25px"> 以上信息来自于http://developer.android.com/sdk/ndk/index.html#requirements.<br style="line-height:25px"><span style="line-height:25px">注意</span>:<span style="color:#ff6600; line-height:25px"><wbr style="line-height:25px">Android的这个文档有点误导人<wbr style="line-height:25px">。</wbr></wbr></span><br style="line-height:25px"><span style="color:#000080; line-height:25px">对于Linux平台需要GNUMake3.81orlater,或Arecentversionofawk(eitherGNUAwkorNawk)。<br style="line-height:25px"> 虽然对于Windows也需要GNUMake3.81orlater,或Arecentversionofawk(eitherGNUAwkorNawk)。<br style="line-height:25px"> 但是实际上如果对</span><span style="color:#ff6600; line-height:25px">Cygwin1.7orhigher是完全安装的话</span>,<wbr style="line-height:25px"><span style="color:#ff6600; line-height:25px">Cygwin就已经包含了GNUMake和awk的window版本</span><span style="line-height:25px">。</span><br style="line-height:25px"><span style="color:#000080; line-height:25px">因此Window平台下,其实对Cygwin进行完全安装就行了<wbr style="line-height:25px">。<br style="line-height:25px"> 在http://developer.android.com/sdk/ndk/index.html#requirements还有很多有用信息,可以参阅。</wbr></span><br style="line-height:25px"><span style="line-height:25px">GNUMake下载地址</span><br style="line-height:25px"><span style="color:#000080; line-height:25px">linux版本</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">http://ftp.gnu.org/gnu/make/</span><br style="line-height:25px"><span style="line-height:25px">awk下载地址</span>:<br style="line-height:25px"><span style="color:#000080; line-height:25px">linux版本</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">http://linux.softpedia.com/get/Text-Editing-Processing/Filters/GNU-awk-207.shtml<br style="line-height:25px"></span><span style="color:#000080; line-height:25px">window版本</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">http://www.softpedia.com/get/CD-DVD-Tools/CD-DVD-Images-Utils/Gawk-for-Windows.shtml</span><br style="line-height:25px"><span style="line-height:25px">gawk下载地址</span>:<br style="line-height:25px"><span style="color:#3366ff; line-height:25px">http://ftp.gnu.org/gnu/gawk/</span><br style="line-height:25px"><span style="line-height:25px">Cygwin下载地址</span>。</wbr></wbr> </div> <div style="line-height:25px"> <span style="color:#3366ff; line-height:25px">http://www.cygwin.com/</span><br style="line-height:25px"><wbr style="line-height:25px">关于Cygwin安装步骤请参阅《<strong><a title="阅读全文" target="_blank" href="http://hubingforever.blog.163.com/blog/static/17104057920116641557558/" style="color:rgb(207,121,28); line-height:25px; text-decoration:none">cygwin安装详解</a></strong>》</wbr> </div> <div style="line-height:25px"> <span style="line-height:25px">注意</span>:<wbr style="line-height:25px">Cygwin的安装包选项那屏,点击包菜单根的"All"后面的"Default",然它变成"install",就是完全安装。</wbr> </div> <div style="line-height:25px"> <span style="color:#003366; line-height:25px">在安装AndroidNDK后:</span><br style="line-height:25px"><span style="color:#003366; line-height:25px">在其samples目录下找到很多实例程序</span><br style="line-height:25px"><span style="color:#003366; line-height:25px">在其docs目录下可以看到有很多帮助文档,</span><br style="line-height:25px"><span style="color:#000080; line-height:25px">首先阅读的应该是OVERVIEW.TXT。<br style="line-height:25px"> 关于Android.mk文件的编写在ANDROID-MK.TXT中<br style="line-height:25px"> 关于Application.mk文件的编写在APPLICATION-MK.TXT中<br style="line-height:25px"> 关于AndroidNDK的安装要求在INSTALL.TXT中。</span><br style="line-height:25px"> 如何在Eclipse中进行android的JNI开发。<br style="line-height:25px"><span style="line-height:25px"><wbr style="line-height:25px">1,首先需要在Eclipse建个Android工程</wbr></span><wbr style="line-height:25px">。<br style="line-height:25px"><span style="color:#000080; line-height:25px">工程名为JniHello,Activity名为HelloActivity</span><br style="line-height:25px"><span style="line-height:25px"><wbr style="line-height:25px">2,HelloActivity中载入一个JNI包</wbr></span><wbr style="line-height:25px">。<br style="line-height:25px"><span style="color:#000080; line-height:25px">在使用JNI的接口前,需要载入JIN的包。<br style="line-height:25px"> 我这里的JIN包名为hello-jni<br style="line-height:25px"> (其文件名为lib+包名+.so,即libhello-jni.so)。<br style="line-height:25px"> HelloActivity中载入如下:<br style="line-height:25px"> static{<br style="line-height:25px"> System.loadLibrary("hello-jni");<br style="line-height:25px"> }</span><br style="line-height:25px"> 3,<span style="line-height:25px"><wbr style="line-height:25px">在Java声明一个JNI函数</wbr></span><wbr style="line-height:25px">:<br style="line-height:25px"><span style="color:#000080; line-height:25px">nativeStringgetStringFromJni();</span><br style="line-height:25px"> 4,<span style="line-height:25px"><wbr style="line-height:25px">在Java中使用JIN函数和一般的java函数一样</wbr></span><wbr style="line-height:25px">。<br style="line-height:25px"><span style="color:#3366ff; line-height:25px">publicvoidonCreate(BundlesavedInstanceState){<br style="line-height:25px"> super.onCreate(savedInstanceState);<br style="line-height:25px"> setContentView(R.layout.main);<br style="line-height:25px"> TextViewtextView=(TextView)findViewById(R.id.textView1);<br style="line-height:25px"> textView.setText(</span><span style="color:#ff6600; line-height:25px">getStringFromJni())</span><span style="color:#3366ff; line-height:25px">;<br style="line-height:25px"> }</span><br style="line-height:25px"> 5,<span style="line-height:25px"><wbr style="line-height:25px">建立jni源代码的目录jni</wbr></span><wbr style="line-height:25px">.<br style="line-height:25px"> 在JniHello下建立个jni目录。</wbr></wbr></wbr></wbr></wbr> </div> <div style="line-height:25px"><span style="line-height:25px">6,在头文件中声明C\C++的Jni函数</span></div> <div style="line-height:25px"> <span style="line-height:25px; font-family:Arial,Helvetica,simsun,u5b8bu4f53"></span> <div style="line-height:22px"><span style="color:#003366; line-height:22px">如果你需要不同的JNI的C\C++实现文件的函数能互相调用,那么你就需要为你的JNI的C\C++端编写扩展名为h的头文件。</span></div> <div style="line-height:22px"><span style="color:#003366; line-height:22px">你可以手写头文件,也可以使用javah命令。</span></div> <div style="line-height:22px"> <span style="color:#003366; line-height:22px">关于javah命令的详细内容请参考《</span><strong><a title="阅读全文" target="_blank" href="http://hubingforever.blog.163.com/blog/static/17104057920115218559186/" style="color:rgb(207,121,28); line-height:22px; text-decoration:none">javah命令详解</a></strong><span style="line-height:22px; color:rgb(0,51,102)">》</span> </div> <div style="line-height:22px"><span style="line-height:22px; color:rgb(0,51,102)">这里我不需要不同的JNI的C\C++实现文件的函数进行调用,因此略去该步骤。</span></div> <span style="line-height:25px"><wbr style="line-height:25px">7,定义Jni函数</wbr></span><wbr style="line-height:25px">。</wbr> </div> <div style="line-height:25px"> <span style="color:#000080; line-height:25px">在目录jni下新建个文件hello-jni.c如下:<br style="line-height:25px"> #include<string.h><br style="line-height:25px"> #include<jni.h><br style="line-height:25px"></span><span style="color:#99cc00; line-height:25px"></span><span style="color:#ff9900; line-height:25px">jstring</span><br style="line-height:25px"><span style="color:#000080; line-height:25px"></span><span style="color:#ff9900; line-height:25px">Java</span><span style="color:#000080; line-height:25px">_</span><span style="color:#ff6600; line-height:25px">c</span><span style="color:#ff6600; line-height:25px">om_teleca_robin_HelloActivity</span><span style="color:#000080; line-height:25px">_</span><span style="color:#ff9900; line-height:25px">getStringFromJni</span><span style="color:#000080; line-height:25px">(JNIEnv*env,<br style="line-height:25px"> jobjectthiz)<br style="line-height:25px"> {<br style="line-height:25px"> return(*env)->NewStringUTF(env,"Hellorobin,thisworldisfromJNI!");<br style="line-height:25px"> }</span><span style="line-height:25px"><br style="line-height:25px"> 函数返回类型</span><br style="line-height:25px"><span style="color:#ff9900; line-height:25px">jstring</span><span style="color:#0000ff; line-height:25px">代表的是返回类型。这里应该表示的是java的String.</span><br style="line-height:25px"><span style="line-height:25px">函数名字</span><br style="line-height:25px"><span style="color:#0000ff; line-height:25px">函数名字首先是前缀java,然后是要调用该JNI的Java类的路径,</span><br style="line-height:25px"><span style="color:#0000ff; line-height:25px">接着是Java中申明的函数的名字</span>。<br style="line-height:25px"><span style="line-height:25px">函数参数</span><br style="line-height:25px"><span style="color:#0000ff; line-height:25px">第一个参数永远应该是JNIEnv*env,<br style="line-height:25px"> 第二个参数jobjectthiz是java中的this指针。<br style="line-height:25px"> 第三个参数开始是Java的函数中的参数。</span><br style="line-height:25px"><span style="color:#000080; line-height:25px">比如实例bitmap-plasma中的Plasma对renderPlasma声明如下:</span><br style="line-height:25px"><span style="color:#993300; line-height:25px">privatestaticnativevoid</span><span style="color:#0000ff; line-height:25px">renderPlasma(Bitmapbitmap,longtime_ms);</span><br style="line-height:25px"><span style="color:#000080; line-height:25px">在jni中则为</span><br style="line-height:25px"><span style="color:#0000ff; line-height:25px">JNIEXPORTvoidJNICALLJava_com_example_plasma_PlasmaView_renderPlasma(JNIEnv*env,jobjectobj,jobjectbitmap,jlongtime_ms)<br style="line-height:25px"></span> </div> <div style="line-height:25px"> <span style="color:#000080; line-height:25px">关于JNI中参数的传递与操作的更多内容请参考《</span><strong><a title="阅读全文" target="_blank" href="http://hubingforever.blog.163.com/blog/static/17104057920115712234774/" style="color:rgb(207,121,28); line-height:25px; text-decoration:none">JNI中参数的传递与操作</a></strong><span style="line-height:25px; color:rgb(0,0,128)">》</span> </div> <div style="line-height:25px"> <span style="line-height:25px">注意</span>:JNIEXPORT和JNICALL都是JNI的关键字,表示此函数是要被JNI调用的</div> <div style="line-height:25px"> <div style="line-height:25px"><span style="color:#000080; line-height:25px">应用层级的Java类别通过VM而调用到本地函数,VM默认是按照JNI的java函数和C\C++本地函数的命名规范,去寻找*.so里的本地函数。</span></div> <div style="line-height:25px"><span style="color:#000080; line-height:25px">查找的过程还是有点耗时。如果调用次数很多,而每次都寻找一遍的话,会花掉许多时间。</span></div> <div style="line-height:25px"><span style="color:#000080; line-height:25px">如果你想节约VM查找JNI本地函数的时间,你可以通过registerNativeMethods()函数把JNI本地函数向VM进行登记,以节约VM查找JNI本地函数的时间。</span></div> <div style="line-height:25px"><span style="color:#000080; line-height:25px">如果你的JNI本地函数的命名没严格遵守java函数和C\C++本地函数对应的命名规范,你必须通过registerNativeMethods()函数把JNI本地函数向VM进行登记,以便VM能找到你的JNI本地函数。</span></div> </div> <div style="line-height:25px">关于JNI本地函数向VM进行登记,请参照《<strong><a title="阅读全文" target="_blank" href="http://hubingforever.blog.163.com/blog/static/171040579201151835834200/" style="color:rgb(207,121,28); line-height:25px; text-decoration:none">JNI系统程序开发</a></strong>》</div> <div style="line-height:25px"><wbr style="line-height:25px"><span style="line-height:25px">8,编辑Android.mk</span><wbr style="line-height:25px"><br style="line-height:25px"><span style="color:#000080; line-height:25px">在jni下新建Android.mk文件如下:<br style="line-height:25px"> LOCAL_PATH:=$(callmy-dir)<br style="line-height:25px"> include$(CLEAR_VARS)<br style="line-height:25px"> LOCAL_MODULE:=hello-jni<br style="line-height:25px"> LOCAL_SRC_FILES:=hello-jni.c<br style="line-height:25px"></span><span style="color:#000080; line-height:25px">include$(BUILD_SHARED_LIBRARY)。</span></wbr></wbr></div> <div style="line-height:25px"> <span style="line-height:25px; font-family:Arial,Helvetica,simsun,u5b8bu4f53">关于<span style="line-height:22px">Android.mk的更多内容请参照《</span><strong><a title="阅读全文" target="_blank" href="http://hubingforever.blog.163.com/blog/static/171040579201152185542166/" style="color:rgb(207,121,28); line-height:22px; text-decoration:none">Android.mk</a></strong>》</span><span style="color:#000080; line-height:25px"><br style="line-height:25px"></span><span style="line-height:25px">9,编译JNI</span><wbr style="line-height:25px"><br style="line-height:25px"><span style="color:#000080; line-height:25px">在cygwin\home\hubin的.bash_profile文件中添加设置ndk的路径。</span><br style="line-height:25px"><span style="color:#000080; line-height:25px">NDK=/cygdrive/d/SDK/android-ndk-r4b</span><br style="line-height:25px"><span style="color:#000080; line-height:25px">exportNDK。</span><br style="line-height:25px"><span style="color:#000080; line-height:25px">programs->Cygwin->Cygwin Bash Shell或直接点击cygwin\Cygwin.bat打开cygwinbashshell窗口,</span><br style="line-height:25px"><span style="color:#000080; line-height:25px">然后进入工程JniHello的根目录</span><br style="line-height:25px"><span style="color:#ff6600; line-height:25px">执行$NDK/ndk-build。</span><br style="line-height:25px"><span style="color:#000080; line-height:25px">这时应该就能在JniHello的根目录的libs\armeabi下生成libhello-jni.so。</span><br style="line-height:25px"><span style="line-height:25px">注意</span><span style="color:#000080; line-height:25px">:在cygwin中进入一个盘符的命令为cdD:的形式</span></wbr> </div> <div style="line-height:25px">关于Cygwin的使用的更多内容请参阅《<strong><a title="阅读全文" target="_blank" href="http://hubingforever.blog.163.com/blog/static/171040579201161932655494/" style="color:rgb(207,121,28); line-height:25px; text-decoration:none">Cygwin使用指南</a></strong>》</div> <div style="line-height:25px"> <span style="line-height:25px">10,在Ecplise中重新打包生成apk文件,libhello-jni.so也同时被打进了apk</span><wbr style="line-height:25px">.<br style="line-height:25px"><span style="line-height:25px"><wbr style="line-height:25px">11,像运行一般android程序一样运行该程序</wbr></span><wbr style="line-height:25px">。<br style="line-height:25px"><span style="color:#000080; line-height:25px">在jni函数中向android的控制台打印信息可以采用以下的方式。<br style="line-height:25px"> #include<android/log.h><br style="line-height:25px"> #defineLOGI(...)__android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)<br style="line-height:25px"> #defineLOGE(...)__android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)<br style="line-height:25px"> LOGI("frame/s(avg,min,max)=(%.1f,%.1f,%.1f)"<br style="line-height:25px"> "rendertimems(avg,min,max)=(%.1f,%.1f,%.1f)\n",<br style="line-height:25px"> 1000./avgFrame,1000./maxFrame,1000./minFrame,<br style="line-height:25px"> avgRender,minRender,maxRender);</span><br style="line-height:25px"><wbr style="line-height:25px">关于如何定义多个JNI包(module),请参考android-ndk-r4b\samples\two-libs</wbr></wbr></wbr> </div> <div style="line-height:25px">关于jni的使用可以参照《<strong><a title="阅读全文" target="_blank" href="http://hubingforever.blog.163.com/blog/static/17104057920115992114907/" style="color:rgb(207,121,28); line-height:25px; text-decoration:none">JNI应用程序开发实例1</a></strong>》</div> </wbr></wbr>