Android NDK(JNI)開發

來源:互聯網
上載者:User

標籤:eclipse   android   windows   jni   java   

《基於Windows平台,Android NDK(JNI)開發技術》


【摘要】本文介紹如何基於Windows平台,在Eclipse中使用Android NDK技術實現“Android平台上的JNI ( Java Native Interface ) ”開發。Android NDK開發需要一定的Java JNI技術基礎。Android NDK實質,可以簡單的認為是Android平台提供的一組套件,將一些C/C++代碼通過JNI的形式為Android平台所複用,該技術可以使得以往寫好的、成熟的C/C++代碼不加修改或者稍加修改即可移植到Android。同時,在一些敏感的特殊情境,可能需要C/C++代碼,如CPU敏感,圖形映像等。
【關鍵詞】Android , NDK , JNI , Windows


Android平台的NDK(Native Development Kit)開發,需要從Google官方下載Android NDK所需的SDK開發包。在舊版本的Android NDK開發中,需要額外的下載安裝第三方Cygwin,但是最新Android NDK已經整合Cygwin功能,不需要再單獨下載整合Cygwin,即免Cygwin安裝。Android NDK官方下載頁面:https://developer.android.com/ndk/downloads/index.html ,本文中下載和使用的Android NDK版本是基於64位Windows的Android NDK r10e版 :

版本名:Windows 64-bit , android-ndk-r10e-windows-x86_64.exe
下載連結:http://dl.google.com/android/ndk/android-ndk-r10e-windows-x86_64.exe

Windows 64-bit , android-ndk-r10e-windows-x86_64.exe下載完畢後是這樣一個檔案:


實際上是一個包含Android NDK開發資源的壓縮檔,點擊安裝後將其解壓到一個檔案夾下。本例是放在:D:\Program\android\ndk目錄下。

然後開啟Eclipse。Windows -> Preferences -> Android -> NDK,


在NDK Location中,選擇剛才安裝的Android NDK目錄。
至此,Android NDK開發環境搭建完成。

接下來就是如何使用和具體開發。
建立一個NDKTest的Android項目:



然後為項目NDKTest增加NDK:Add Native Support,在NDKTest的項目單擊右鍵,Android Tools -> Add Native Support ,


當Add Natvie Support後,Eclipse彈出對話方塊,提示指定lib名字,預設就是項目名,本例就用NDKTest作為lib名字。


(注意:Android NDK會自動為庫添加首碼 “lib”,這樣最後的庫名為“libxxx.so”,假設在自己的項目中本來就是lib開頭,那麼Android NDK則不再添加“lib”首碼,直接使用你自己命名好的名稱。)

此時項目的目錄中會自動產生一個jni的子目錄,jni下有兩個檔案:NDKTest.cpp和Android.mk,

其中Android.mk不需要我們修改,而NDKTest.cpp則是我們後面需要增加自己實現的內容。
通常,一個項目中所需要的NDK\JNI庫\方法最好放在一個共同的Java類中,這樣方便管理和代碼維護。本例中,新增一個 MyJNI.java的類檔案,在MyJNI.java這個類檔案中,函數開頭冠以native修飾符的,修飾符native表明這就是我們將要實現的JNI函數,寫好的MyJNI.java檔案內容及存放位置和內容



注意需要首先在此類中使用靜態代碼塊包裹一層,load我們的庫檔案。

到這裡,剩下的代碼工作就是完成native方法。Run一下這個項目,此時Run這個項目沒有意義,我們只是為了獲得編譯後的*.class檔案才Run,拿到.class類檔案後才能使用javah編譯命令獲得jni的標頭檔。
Run過後,在NDKTest/bin/classses目錄下已經產生編譯好的類檔案包,

接下來我們要獲得MyJNI.java相對應的JNI標頭檔,啟動java控制台定位到classes目錄下,然後執行javah命令:javah zhangphil.ndktest.MyJNI,


如果一切正常,那麼此時就會在classes目錄下產生:zhangphil_ndktest_MyJNI.h標頭檔,不要對這個代碼檔案進行修改。zhangphil_ndktest_MyJNI.h裡面的代碼內容如下:

/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class zhangphil_ndktest_MyJNI */#ifndef _Included_zhangphil_ndktest_MyJNI#define _Included_zhangphil_ndktest_MyJNI#ifdef __cplusplusextern "C" {#endif/* * Class:     zhangphil_ndktest_MyJNI * Method:    getString * Signature: ()Ljava/lang/String; */JNIEXPORT jstring JNICALL Java_zhangphil_ndktest_MyJNI_getString  (JNIEnv *, jobject);#ifdef __cplusplus}#endif#endif


將 zhangphil_ndktest_MyJNI.h此標頭檔複製到jni目錄下,結構層次


開啟由IDE自動產生的NDKTest.cpp檔案,裡面其實只有一行代碼:


接下來,
1, 我們將此檔案的頭部分include我們的zhangphil_ndktest_MyJNI.h檔案。
2, 實現在zhangphil_ndktest_MyJNI.h檔案中定義的:

JNIEXPORT jstring JNICALL Java_zhangphil_ndktest_MyJNI_getString  (JNIEnv *, jobject);

Native方法。

(備忘:Java_zhangphil_ndktest_MyJNI_getString(),這是一個由Java系統自動產生的JNI簽名函數,其規律特點是Java開頭,然後就是我們自己的包名,接著是類名,最後就是我們自己定義的native方法,只不過Java命名規則中的 “.” 由 “_” 取代 )

補寫完成NDKTest.cpp,簡單期間,假設我們的getString()函數僅僅返回“Hello , World ! I‘m from JNI !”字串:

#include <jni.h>#include <zhangphil_ndktest_MyJNI.h>JNIEXPORT jstring JNICALL Java_zhangphil_ndktest_MyJNI_getString  (JNIEnv * env, jobject obj){returnenv->NewStringUTF("Hello , World ! I'm from JNI !");}


至此,Android JNI的全部代碼已經完成,剩下的就是使用我們的native方法。
寫一個簡單的Android Activity測試我們完成的Android native函數。

package zhangphil.ndktest;import android.support.v7.app.ActionBarActivity;import android.widget.Toast;import android.os.Bundle;public class MainActivity extends ActionBarActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);MyJNI jni = new MyJNI();String s = jni.getString();Toast.makeText(this, s, Toast.LENGTH_LONG).show();}}

運行結果



成功了!


總結:

Android NDK開發實際上可以認為就是Android平台架構下的Java JNI,具體步驟歸結如下:
(第1步)下載安裝最新的Android NDK,搭建好開發環境,然後“Add Natvie Support”。
(第2步)寫好自己項目中需要的類和native方法。在本例中就是增加MyJNI類,在MyJNI類中我們寫了一個用以示範的getString()函數,此函數為native。
(第3步)Run這個項目,這階段Run目的只是為了獲得編譯後類檔案。然後啟動java控制台,定位到bin目錄下的classes包,執行javah命令,為我們的MyJNI類檔案產生 .h 標頭檔。在本例中即:zhangphil_ndktest_MyJNI.h檔案。
(第4步)把第3步中獲得的 .h 標頭檔複製到jni目錄下,然後補全jni目錄下的 .cpp 檔案,注意在 .cpp 的頭部需要 #include 我們在第3步產生的 .h 標頭檔。同時,在  .cpp 原始碼檔案中完成在 .h 標頭檔中定義的函數。
在本例中就是在 zhangphil_ndktest_MyJNI.h 定義的函數:

JNIEXPORT jstring JNICALL Java_zhangphil_ndktest_MyJNI_getString  (JNIEnv *, jobject);
</pre><p></p><p>完成後的:</p><p><pre class="cpp" name="code">JNIEXPORT jstring JNICALL Java_zhangphil_ndktest_MyJNI_getString  (JNIEnv * env, jobject obj){returnenv->NewStringUTF("Hello , World ! I'm from JNI !");}

(第5步)以上都完成後,就可以直接在我們的項目中使用 MyJNI類中的native方法getString()了。



著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

Android NDK(JNI)開發

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.