第7章-Android-NDK-《Android程序設(shè)計教程》課件_第1頁
第7章-Android-NDK-《Android程序設(shè)計教程》課件_第2頁
第7章-Android-NDK-《Android程序設(shè)計教程》課件_第3頁
第7章-Android-NDK-《Android程序設(shè)計教程》課件_第4頁
第7章-Android-NDK-《Android程序設(shè)計教程》課件_第5頁
已閱讀5頁,還剩87頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

第七章AndroidNDK1第七章AndroidNDK1主要內(nèi)容7.1AndroidNDK簡介7.2構(gòu)建NDK系統(tǒng)7.3NDK開發(fā)過程詳解2主要內(nèi)容7.1AndroidNDK簡介2AndroidNDK是在SDK前面又加上了“原生”二字,即NativeDevelopmentKit,因此又被Google稱為“NDK”。AndroidNDK是AndroidSDK的伴隨工具,可以讓用戶用諸如C/C++原生編程語言開發(fā)Android應(yīng)用程序。原生SDK的公布可以讓開發(fā)者更加直接的接觸Android系統(tǒng)資源,并極大地提高了Android應(yīng)用程序開發(fā)的靈活性。AndroidNDK需要安裝全部AndroidSDK1.5或以上版本,到目前為止AndroidNDK已經(jīng)修訂了9版本。AndroidNDK集成了交叉編譯器,支持ARM、x86及MIPS處理器指令集、JNI接口和一些穩(wěn)定的庫文件。7.1AndroidNDK簡介3AndroidNDK是在SDK前面又加上了“原生”二字,AndroidNDK具體包括如下:ARM、x86和MIPS交叉編譯器構(gòu)建系統(tǒng)Java原生接口頭文件C庫Math庫POSIX線程最小的C++庫ZLib壓縮庫動態(tài)鏈接庫 AndroidNDK簡介Android日志庫Android像素緩沖區(qū)庫Android原生應(yīng)用APIsOpenGLES3D圖形庫OpenES原生音頻庫OpenMAXAL最小支持4AndroidNDK具體包括如下:AndroidNDK簡

7.2構(gòu)建NDK系統(tǒng)7.2.1AndroidNDK開發(fā)環(huán)境構(gòu)建7.2.2解析hello-jni例程5

7.2構(gòu)建NDK系統(tǒng)7.2.1AndroidNDAndroidNDK的構(gòu)建系統(tǒng)是基于GNUMake的,提供了頭文件、庫和交叉編譯器工具鏈,可以在MicrosoftWindows、AppleMacOSX和Linux三種操作系統(tǒng)平臺上運行。在安裝前要確保已經(jīng)最新版的AndroidSDK和升級應(yīng)用程序和環(huán)境。本書僅介紹MicrosoftWindows系統(tǒng)的NDK系統(tǒng)構(gòu)建,請按照下列步驟操作:7.2.1AndroidNDK開發(fā)環(huán)境構(gòu)建6AndroidNDK的構(gòu)建系統(tǒng)是基于GNUMake的,提第一步,在安裝完成SDK工具后,下載并安裝Cygwin。安裝完成后,要把Cygwin二進(jìn)制路徑添加到系統(tǒng)可執(zhí)行搜索路徑中。操作如下:在“系統(tǒng)屬性”界面打開環(huán)境變量對話框;在系統(tǒng)變量部分單擊New按鈕定義一個新的環(huán)境變量,將變量名設(shè)置成CYGWIN_HOME,將變量值設(shè)置成前面記下的Cygwin安裝目錄;單擊OK按鍵保存新環(huán)境變量;在環(huán)境變量對話框中的系統(tǒng)變量列表中,雙擊PATH變量,并將;%CYGWIN_HOME%\bin追加到變量值后面。7.2.1AndroidNDK開發(fā)環(huán)境構(gòu)建7第一步,在安裝完成SDK工具后,下載并安裝Cygwin。7.第二步,下載最新版AndroidNDK開發(fā)包,目前本書編寫時,最新版本是R9,請根據(jù)需要到Google的官方網(wǎng)站下載AndroidNDK。

/tools/sdk/ndk/index.html完成安裝后將AndroidNDK的二進(jìn)制路徑加到系統(tǒng)可執(zhí)行搜索路徑中,具體方法同上。第三步是配置Cygwin的NDK開發(fā)環(huán)境。修改在用戶目錄下的.bash_profile文件,在該文件的末尾處添加如下代碼:ANDROID_NDK_ROOT=/cygdrive/d/android/android-nkd-r9dExportANDROID_NDK_ROOT上述代碼說明AndroidNDK安裝的目錄,即d盤的android/android-nkd-r9d目錄下。7.2.1AndroidNDK開發(fā)環(huán)境構(gòu)建8第二步,下載最新版AndroidNDK開發(fā)包,目前本書編寫7.2.1AndroidNDK開發(fā)環(huán)境構(gòu)建所有的AndroidNDK組件都被安裝在目標(biāo)目錄下,下面介紹一些重要文件和子目錄。ndk-build:該shell腳本是AndroidNDK構(gòu)建系統(tǒng)的起始點。ndk-gdb:該shell腳本允許用GNU調(diào)試器調(diào)試原生組件。ndk-stack:該shell腳本可以幫助分析原生組件崩潰時的堆棧追蹤。build:該目錄包含可AndroidNDK構(gòu)建系統(tǒng)的所有模塊。platforms:該目錄包含了支持不同Android目標(biāo)版本的頭文件和庫文件。AndroidNDK構(gòu)建系統(tǒng)會根據(jù)具體的Android版本自動引用這些文檔。97.2.1AndroidNDK開發(fā)環(huán)境構(gòu)建所有的Andr7.2.1AndroidNDK開發(fā)環(huán)境構(gòu)建samples:該目錄包含了一些示例應(yīng)用程序,這些程序可以體現(xiàn)AndroidNDK的性能。示例項目對于學(xué)習(xí)使用AndroidNDK的特性很有幫助。sources:該目錄包含了可供開發(fā)人員導(dǎo)入到現(xiàn)有的AndroidNDK項目的一些共享模塊。toolchains:該目錄包含目前AndroidNDK支持的不同目標(biāo)機(jī)體系結(jié)構(gòu)的交叉編譯器。AndroidNDK目前支持ARM、X86和MIPS體系結(jié)構(gòu)。AndroidNDK構(gòu)建系統(tǒng)根據(jù)選定的體系結(jié)構(gòu)使用不同的交叉編譯器。107.2.1AndroidNDK開發(fā)環(huán)境構(gòu)建samples最后測試開發(fā)環(huán)境是否可以正常工作,首先雙擊Cygwin圖標(biāo),出現(xiàn)Cygwin后運行ndk-build出現(xiàn)如圖所示的運行結(jié)果,說明AndroidNDK的開發(fā)環(huán)境已經(jīng)可以正常工作了。7.2.1AndroidNDK開發(fā)環(huán)境構(gòu)建11最后測試開發(fā)環(huán)境是否可以正常工作,首先雙擊Cygwin圖標(biāo),7.2.2解析hello-jni例程首先使用import向Eclipse中導(dǎo)入工程,本機(jī)目錄為F:\android-ndk-r9d\samples\hello-jni。導(dǎo)入工程之后我們會在項目目錄下發(fā)現(xiàn)兩個比較重要的文件一個是src/com.example.hellojni/HelloJni.java文件,一個是jni/hello-jni.c文件。hello-jni.c文件定義了輸出字符串"HellofromJNI!CompiledwithABI"ABI"."的方法,而HelloJni.java文件則通過調(diào)用上述hello.c的動態(tài)鏈接庫來獲取輸出的字符串,并顯示到模擬器上。127.2.2解析hello-jni例程首先使用import向其中c文件內(nèi)容如下:10Java_com_example_hellojni_HelloJni_stringFromJNI(JNIEnv*env,jobjectthiz)11{12#ifdefined(__arm__)13#ifdefined(__ARM_ARCH_7A__)14#ifdefined(__ARM_NEON__)15#defineABI"armeabi-v7a/NEON“16#else17#defineABI"armeabi-v7a"18#endif19#else20#defineABI"armeabi"21#endif22#elifdefined(__i386__)23#defineABI"x86"24#elifdefined(__mips__)25#defineABI"mips"26#else27#defineABI"unknown"28#endif29return(*env)->NewStringUTF(env,“HellofromJNI!CompiledwithABI”ABI“.”);}這里主要的是定義了輸出字符串"HellofromJNI!CompiledwithABI"ABI"."的方法13其中c文件內(nèi)容如下:10Java_com_exa7.2.2解析hello-jni例程其中java文件內(nèi)容如下:5publicclassHelloJniextendsActivity{6publicvoidonCreate(BundlesavedInstanceState){7super.onCreate(savedInstanceState);8TextViewtv=newTextView(this);9tv.setText(stringFromJNI());10setContentView(tv);}11publicnativeStringstringFromJNI();12publicnativeStringunimplementedStringFromJNI();13static{14 System.loadLibrary("hello-jni");15}16}通過調(diào)用上述hello.c的動態(tài)鏈接庫來獲取輸出的字符串,并顯示到模擬器上。

147.2.2解析hello-jni例程其中java文件內(nèi)容如7.2.2解析hello-jni例程接著啟動Cygwin命令行輸入cdf:/android-ndk-r9d/samples/hello-jni進(jìn)入到NDK主目錄,然后編譯C代碼,其命令如下:../../ndk-build,在Cygwin中顯示如圖所示。157.2.2解析hello-jni例程接著啟動Cygwin命7.2.2解析hello-jni例程此時表明已生成所需的動態(tài)鏈接庫,接下來我們要對其進(jìn)行加載。在Eclipse的ProjectExplorer視圖中右擊HelloJni,依次選擇Androidtools、AddNativeSupport在彈出的對話框中顯示信息如圖所示。由于該項目已經(jīng)包含了一個原生項目,所以庫名可以保持不變,點擊finish即可完成加載。在Android模擬器上運行該項目,其運行效果如下:167.2.2解析hello-jni例程此時表明已生成所需的動7.3NDK開發(fā)過程詳解7.3.1中間件概念7.3.2Android系統(tǒng)的中間件7.3.3使用C/C++實現(xiàn)本地方法7.3.4依賴關(guān)系建立7.3.5NDK程序的鏈接與運行177.3NDK開發(fā)過程詳解7.3.1中間件概念177.3NDK開發(fā)過程詳解AndroidNDK構(gòu)建系統(tǒng)所提供的不同功能,例如建立一個共享庫建立多種共享庫建立靜態(tài)庫利用共享庫通用模塊在多種NDK項目間共享模塊使用預(yù)建庫建立獨立的可執(zhí)行文件其他構(gòu)建系統(tǒng)變量和宏定義新變量和條件操作187.3NDK開發(fā)過程詳解AndroidNDK構(gòu)建系統(tǒng)所提在進(jìn)行NDK開發(fā)時,一般需要同時建立Android工程和C/C++工程,然后使用NDK編譯C/C++工程,形成可以被調(diào)用的共享庫,最后共享庫文件會被拷貝到Android工程中,并被打包到apk文件中。其開發(fā)過程可分為以下幾步:設(shè)計JNI接口用C/C++實現(xiàn)本地的方法編譯文件的實現(xiàn)生成動態(tài)連接庫。7.3NDK開發(fā)過程詳解19在進(jìn)行NDK開發(fā)時,一般需要同時建立Android工程和C/中間件(Middleware)是處于操作系統(tǒng)和應(yīng)用程序之間的軟件,它包括一組服務(wù),以便于運行在一臺或多臺機(jī)器上的多個軟件通過網(wǎng)絡(luò)進(jìn)行交互。該架構(gòu)通常用于支持分布式應(yīng)用程序并簡化其復(fù)雜度,它包括web服務(wù)器、事務(wù)監(jiān)控器和消息隊列軟件。中間件能夠屏蔽操作系統(tǒng)和網(wǎng)絡(luò)協(xié)議的差異,為應(yīng)用程序提供多種通訊機(jī)制;并提供相應(yīng)的平臺以滿足不同領(lǐng)域的需要。中間件帶給應(yīng)用系統(tǒng)的,不只是開發(fā)的簡便、開發(fā)周期的縮短,也減少了系統(tǒng)的維護(hù)、運行和管理的工作量,還減少了計算機(jī)總體費用的投入。7.3.1中間件概念20中間件(Middleware)是處于操作系統(tǒng)和應(yīng)用程序之間的中間件是操作系統(tǒng)與應(yīng)用程序的溝通橋梁,并分為兩層:函數(shù)層(Library)和虛擬機(jī)(VirtualMachine)。應(yīng)用程序用Java語言開發(fā),操作系統(tǒng)代碼則是C代碼,它們之間的通信需要用JNI來實現(xiàn)。JNI一般有以下一些應(yīng)用場景:高性能,在一些情況下因為處理運算量非常大,為了獲取高性能,直接使用java是不能勝任的,如:一些圖形的處理;調(diào)用一些硬件的驅(qū)動或者一些軟件的驅(qū)動,比如調(diào)用一些外部系統(tǒng)接口的驅(qū)動,如:讀卡器的驅(qū)動,OCI驅(qū)動;需要使用大內(nèi)存,遠(yuǎn)遠(yuǎn)超過VM所能分配的內(nèi)存,如:進(jìn)程內(nèi)Cache;調(diào)用C或者操作系統(tǒng)提供的服務(wù),如:java調(diào)用搜索服務(wù),搜索是由C/C++實現(xiàn)的。7.3.2Android系統(tǒng)的中間件21中間件是操作系統(tǒng)與應(yīng)用程序的溝通橋梁,并分為兩層:函數(shù)層(L通常JNI的使用自上至下有4層,本地庫,JNI庫,聲明本地接口的Java類,Java調(diào)用者,JNI在Android層次結(jié)構(gòu)中的作用如圖所示。7.3.2Android系統(tǒng)的中間件22通常JNI的使用自上至下有4層,本地庫,JNI庫,聲明本地接實現(xiàn)JNI需要在C++代碼中實現(xiàn)JNI的各種方法,并注冊到系統(tǒng)中,另外還要在Java源代碼中聲明。[例7-2]實例實現(xiàn)JNI接口的設(shè)計。在此之前我們需要將將NDK與Cygwin關(guān)聯(lián)起來,即打開<Cygwin安裝目錄>\home\Administrator\.bash_profile文件(本文F:\cygwin\home\mwy\.bash_profile,在文件中加入如下代碼:1 NDK_ROOT=/cygdrive/f/android-ndk-r9d/2 exportNDK_ROOT3 PATH+=:$NDK_ROOT4 exportPATH7.3.2Android系統(tǒng)的中間件23實現(xiàn)JNI需要在C++代碼中實現(xiàn)JNI的各種方法,并注冊到系接口設(shè)計過程如下:在NDK安裝目錄下新建文件夾apps,在apps下新建目錄san-angeles(這個名字可以自己任意取),并Eclipse中新建工程SanAngeles。建立工程之后需要創(chuàng)建并編寫JNI類代碼,用來聲明要調(diào)用的本地方法,關(guān)鍵字native。此時在Eclipse中新建名為JNITest的類。7.3.2Android系統(tǒng)的中間件24接口設(shè)計過程如下:7.3.2Android系統(tǒng)的中間件24其代碼如下:1 packagecom.example.SanAngeles;2 publicclassJNITest{3 privatestaticnativevoidnativeInit();4 privatestaticnativevoidnativeResize(intw,inth);5 privatestaticnativevoidnativeRender();6privatestaticnativevoidnativeDone();7 }7.3.2Android系統(tǒng)的中間件25為調(diào)用內(nèi)核代碼提供的接口其代碼如下:7.3.2Android系統(tǒng)的中間件25為調(diào)用編譯Java文件,并生成相應(yīng)的頭文件我們需要將新建的JNItest.java文件復(fù)制到工程目錄的bin目錄下并用命令行編譯。首先進(jìn)入NDK主目錄,接著輸入

>javacJNITest.java即可生成JNItest.class文件。將此文件復(fù)制到F:\android-ndk-r9d\apps\san-angeles\project\bin\classes\com\example\SanAngeles中替換原有文件;從命令行進(jìn)入bin/classes目錄,輸入

>javah–jnicom_example_angles_JNITest生成com_example_angles_JNITest.h的C頭文件,最后在此工程目錄下(即project目錄下)創(chuàng)建jni文件夾,并將生成的頭文件復(fù)制到此處。這個頭文件主要是來處理C/C++和Java中一些定義的差別。而其中的JNIEXPORT和JNICALL都是JNI的關(guān)鍵字,表示函數(shù)式要被JNI調(diào)用的。7.3.2Android系統(tǒng)的中間件26編譯Java文件,并生成相應(yīng)的頭文件7.3.2Androi編譯Java文件,并生成相應(yīng)的頭文件其內(nèi)容如下:7.3.2Android系統(tǒng)的中間件1 #include<jni.h>2 /*Headerforclasscom_example_angles_JNITest*/3 #ifndef_Included_com_example_angles_JNITest4 #define_Included_com_example_angles_JNITest5 #ifdef__cplusplus6 extern"C"{7 #endif8 /*9 *Class:com_example_angles_JNITest10 *Method:nativeInit11 *Signature:()V12 */13 JNIEXPORTvoidJNICALLJava_com_example_angles_JNITest_nativeInit(JNIEnv*,jclass);14 /*15 *Class:com_example_angles_JNITest16 *Method:nativeResize17 *Signature:(II)V27編譯Java文件,并生成相應(yīng)的頭文件7.3.2Androi7.3.2Android系統(tǒng)的中間件18 */19 JNIEXPORTvoidJNICALLJava_com_example_angles_JNITest_nativeResize(JNIEnv*,jclass,jint,jint);20 /*21 *Class:com_example_angles_JNITest22 *Method:nativeRender23 *Signature:()V24 */25 JNIEXPORTvoidJNICALLJava_com_example_angles_JNITest_nativeRender(JNIEnv*,jclass);26 /*27 *Class:com_example_angles_JNITest28 *Method:nativeDone29 *Signature:()V30 */31 JNIEXPORTvoidJNICALLJava_com_example_angles_JNITest_nativeDone(JNIEnv*,jclass);32 #ifdef__cplusplus33 }34 #endif35 #endif這個頭文件主要是來處理C/C++和Java中一些定義的差別。而其中的JNIEXPORT和JNICALL都是JNI的關(guān)鍵字,表示函數(shù)式要被JNI調(diào)用的287.3.2Android系統(tǒng)的中間件18 */這個頭文件在jni目錄下新建app-android.c文件并編寫其代碼,這里我們重點介紹這幾個原生方法的實現(xiàn):Java_com_example_angles_JNITest_nativeInit這個命名必須遵循“函數(shù)名=Java_開頭+包名和類名+接口名”這一規(guī)律。這個名字要是錯了就無法被調(diào)用到。7.3.3使用C/C++實現(xiàn)本地方法1voidJava_com_example_angles_JNITest_nativeInit(JNIEnv*env){2 ImportGLInit();3 appInit();4 gAppAlive=1;5 sDemoStopped=0;6 sTimeOffsetInit=0;}29在jni目錄下新建app-android.c文件并編寫其代碼在上述方法中有兩個常見的參數(shù),其中一個參數(shù)JNIEnv是指向可用JNI函數(shù)表的接口指針;另一個參數(shù)jobject是Java引用。下面將對這兩個參數(shù)做詳細(xì)介紹。JNIEnv接口指針示意圖如下:7.3.3使用C/C++實現(xiàn)本地方法30在上述方法中有兩個常見的參數(shù),其中一個參數(shù)JNIEnv是指向JNIEnv接口指針JNIEnv接口指針,指向一個函數(shù)表,函數(shù)表中的每一個入口指向一個JNI函數(shù)。JNIEnv是一個與線程相關(guān)的變量,不同線程的JNIEnv彼此獨立。在C與C++中使用JNIEnv*env分別如下:C:(*env)->方法名(env,參數(shù)列表)C++:env->方法名(參數(shù)列表)參數(shù)jobject代表的是一個原生實例的方法,它與類實例相關(guān),它們只能在類實例中調(diào)用,通過第二個參數(shù)獲取實例引用。在原生代碼不僅可以通過實例方法實現(xiàn)開可以通過靜態(tài)方法實現(xiàn),與實例方法不同的是第二參數(shù)為jclass值類型的,而且它沒有與實例綁定,可以在靜態(tài)上下文直接引用。7.3.3使用C/C++實現(xiàn)本地方法31JNIEnv接口指針7.3.3使用C/C++實現(xiàn)本地方法3通過C語言來實現(xiàn)OpenGL編程,來說明依賴關(guān)系的建立。具體可參見工程中其余的代碼。7.3.4依賴關(guān)系建立32通過C語言來實現(xiàn)OpenGL編程,來說明依賴關(guān)系的建立。具體AndroidNDK構(gòu)建系統(tǒng)依賴另外二個文件:Android.mk和Application.mk,這兩個文件應(yīng)該作為NDK項目的一部分由開發(fā)人員提供,下面我們將重點介紹。Android.mk文件:Android.mk是向AndroidNDK系統(tǒng)項目中GUNMakefile文件,用于描述實現(xiàn)嵌入的必備信息,因此也是每個NDK項目的必備組件。針對上述的工程,需添加的Android.mk的文件內(nèi)容如下。7.3.4依賴關(guān)系建立1. LOCAL_PATH:=$(callmy-dir)2. include$(CLEAR_VARS)3. LOCAL_MODULE:=hello-jni4. LOCAL_SRC_FILES:=hello-jni.c5. include$(BUILD_SHARED_LIBRARY)33AndroidNDK構(gòu)建系統(tǒng)依賴另外二個文件:Androi7.3.4依賴關(guān)系建立1. LOCAL_PATH:=$(callmy-dir)2. include$(CLEAR_VARS)3. LOCAL_MODULE:=hello-jni4. LOCAL_SRC_FILES:=hello-jni.c5. include$(BUILD_SHARED_LIBRARY)Android系統(tǒng)用LOCAL_PATH來表示需要編譯的C/C++代碼所在目錄,my-dir是AndroidNDK編譯系統(tǒng)提供的宏功能,通過調(diào)用該宏功能返回當(dāng)前目錄的位置。Android系統(tǒng)將CLEAR_VARS變量設(shè)置為腳本文件clear-vars.mk的位置,$(CLEAR_VARS)表示清除LOCAL_PATH以外所有LOCAL_開始的變量,例如LOCAL_MODULE與LOCAL_SRC_FILES等變量。因為所有的腳本都將在同一個GNUMake的執(zhí)行上下文中,而且所有變量都是全局變量,因此必須在每次使用前清空所有以前用過的變量。34LOCAL_MODILE用來聲明模塊名稱,模塊名稱必須唯一,而且中間不能存在空格。因為模塊名稱也被用于給NDK編譯系統(tǒng)生成的共享庫文件命名,所以系統(tǒng)自動在模塊名稱前添加lib前綴,然后生成.so文件。LOCAL_SRC_FILES表示編譯模塊時使用的C/C++文件列表。include$(BUILD_SHARED_LIBRARY)表示NDK系統(tǒng)構(gòu)建的共享庫,AndroidNDK編譯系統(tǒng)將BUILD_SHARED_LIBRARY變量設(shè)置成build-shared-library.mk文件的保存位置。7.3.4依賴關(guān)系建立1. LOCAL_PATH:=$Application.mk文件:在進(jìn)行NDK開發(fā)時,在應(yīng)用程序目錄中一定要有Application.mk文件,用來聲明Android工程需要調(diào)用的共享庫或靜態(tài)庫模塊。Application.mk文件通常被放置在$PROJECT/jni/Application.mk下,

$PROJECT指的是項目。另一種方法是將其放在頂層的子目錄下:

$NDK/apps目錄下$NDK/apps/<myapp>/Application.mk,<myapp>是一個簡稱,用于描述你的NDK編譯系統(tǒng)的應(yīng)用程序(這個名字不會生成共享庫或者最終的包)。7.3.4依賴關(guān)系建立35Application.mk文件:在進(jìn)行NDK開發(fā)時,在應(yīng)用針對上述工程需添加的Application.mk文件內(nèi)容如下:1 APP_MODULES:=JNITest2 APP_PROJECT_PATH:=$(callmy-dir)/projectApplication.mk其實是一個小型GNUMakefile片段,它必須定義一些這樣的變量:7.3.4依賴關(guān)系建立36針對上述工程需添加的Application.mk文件內(nèi)容如下APP_PROJECT_PATH:這個變量是強(qiáng)制性的,并且會給出應(yīng)用程序工程的根目錄的一個絕對路徑。APP_MODULES:這個變量是可選的,如果沒有定義,NDK將由在Android.mk中聲明的默認(rèn)的模塊編譯,并且包含所有的子文件(makefile文件)。 APP_OPTIM:這個變量是可選的,用來定義“release”或"debug"。7.3.4依賴關(guān)系建立37APP_PROJECT_PATH:這個變量是強(qiáng)制性的,并且會APP_CFLAGS:當(dāng)編譯模塊中有任何C文件或者C++文件的時候,C編譯器的信號就會被發(fā)出。APP_CPPFLAGS:C++代碼的編譯選項。 APP_ABI:默認(rèn)情況下,AndroidNDK編譯系統(tǒng)會產(chǎn)生“armeabi”ABI二進(jìn)制文件。 APP_STL:在默認(rèn)情況下,NDK通過Androoid自帶的最小化的C++運行庫(system/lib/libstdc++.so)來提供標(biāo)準(zhǔn)C++頭文件.然而,NDK提供了可供選擇的C++實現(xiàn),你可以通過此變量來選擇使用哪個或鏈接到你的程序。 7.3.4依賴關(guān)系建立38APP_CFLAGS:當(dāng)編譯模塊中有任何C文件或者C++文件APP_GNUSTL_FORCE_CPP_FEATURES:在先前的NDK版本中,當(dāng)使用GNUlibstdc++runtime運行庫(通過設(shè)置APP_STL變量為gnustl_static或gnustl_shared)都會強(qiáng)制支持異常和RTTI,在有些極少情況下可能會出現(xiàn)問題,同時會使生成的機(jī)器碼包含不必須的內(nèi)容。 APP_BUILD_SCRIPT:在默認(rèn)情況下,NDK會在jni目錄下查找Android.mk文件并使用它,如果你想修改它,那么在此變量中你可以指定一個你自己的腳本來執(zhí)行,路徑還是以工程頂層目錄為相對路徑。7.3.4依賴關(guān)系建立39APP_GNUSTL_FORCE_CPP_FEATURES:[例7-3]通過NDK手法顯示一個OpenGL視圖。7.3.5NDK程序的鏈接與運行40[例7-3]通過NDK手法顯示一個OpenGL視圖。7.3.首先打開Cygwin輸入“cd$NDK_ROOT”進(jìn)入ndk安裝目錄,輸入“cdapps/mwy”進(jìn)入到配置文件目錄,然后輸入“ndk-build”使其生成.so文件,具體如下圖7.3.5NDK程序的鏈接與運行41首先打開Cygwin輸入“cd$NDK_ROOT”進(jìn)入nd其運行成功后將生成的libs文件夾復(fù)制到工程中(與src同級),接下來便可以調(diào)用本地原生方法加載C/C++中的數(shù)據(jù)。AndroidNDK生成的共享庫名為libJNITest.so,但是loadLibrary方法只采用JNITest這個庫名,再按照所使用的具體操作系統(tǒng)的要求加上必要的前綴和后綴。庫名與Android.mk文件中使用的LOCAL_MODULE構(gòu)建系統(tǒng)變量定義的模塊名相同。loadLibrary的參數(shù)也不包含共享庫的位置。Java庫路徑,也就是系統(tǒng)屬性Java.library.path保存loadLibrary方法在共享庫搜索的目錄列表,Android上的Java庫路徑包含/vendor/lib和/system/lib7.3.5NDK程序的鏈接與運行42其運行成功后將生成的libs文件夾復(fù)制到工程中(與src同級本書例程如下:部分代碼如下:1publicclassDemoActivityextendsActivity{2@Override3protectedvoidonCreate(BundlesavedInstanceState){4super.onCreate(savedInstanceState);5mGLView=newDemoGLSurfaceView(this);6setContentView(mGLView);7}8@Override9protectedvoidonPause(){10 super.onPause();11 mGLView.onPause();12 }13@Override14 protectedvoidonResume(){15 super.onResume();16 mGLView.onResume();17 }18privateGLSurfaceViewmGLView;19//裝在動態(tài)鏈接庫20 static{21 System.loadLibrary("JNITest");22 }23}24classDemoGLSurfaceViewextendsGLSurfaceView{25publicDemoGLSurfaceView(Contextcontext){43本書例程如下:部分代碼如下:4326 super(context);27 mRenderer=newDemoRenderer();28 setRenderer(mRenderer);29 }30

publicbooleanonTouchEvent(finalMotionEventevent){31if(event.getAction()==MotionEvent.ACTION_DOWN){32nativePause();33 }34returntrue;35 }36DemoRenderermRenderer;37privatestaticnativevoidnativePause();38}39classDemoRendererimplementsGLSurfaceView.Renderer{40publicvoidonSurfaceCreated(GL10gl,EGLConfigconfig){41nativeInit();}43publicvoidonSurfaceChanged(GL10gl,intw,inth){44nativeResize(w,h);}46publicvoidonDrawFrame(GL10gl){47nativeRender();48}//聲明原生方法50privatestaticnativevoidnativeInit();51privatestaticnativevoidnativeResize(intw,inth);52privatestaticnativevoidnativeRender();53privatestaticnativevoidnativeDone();}4426 super(context);44本書例程運行如下:7.3.5NDK程序的鏈接與運行代碼25-38行我們用一個GLSurfaceView類來顯示一個OpenGL視圖,而在GLSurfaceView類中實現(xiàn)了一個Render接口。代碼39-48行則是Render接口的具體實現(xiàn)。代碼第51-54行是對原生方法的聲明,該聲明中含有關(guān)鍵字native以通知Java編譯器,他用另一種語言提供該方法的具體實現(xiàn)。45本書例程運行如下:7.3.5NDK程序的鏈接與運行代碼25本章小結(jié)本章主要介紹了AndroidNDK的相關(guān)知識,從NDK的簡單介紹到開發(fā)環(huán)境的配置、以及開發(fā)流程,使用NDK實現(xiàn)一些對代碼性能要求較高的模塊并將這些模塊嵌入到Android應(yīng)用程序中會大大的提高程序效率,比如上面介紹的用NDK開發(fā)OpenGL。此外,如果項目中包含了大量的邏輯計算或者是3D特效,這時AndroidNDK便會顯示出它超強(qiáng)的功能。46本章小結(jié)本章主要介紹了AndroidNDK的相關(guān)知識,從N第七章AndroidNDK47第七章AndroidNDK1主要內(nèi)容7.1AndroidNDK簡介7.2構(gòu)建NDK系統(tǒng)7.3NDK開發(fā)過程詳解48主要內(nèi)容7.1AndroidNDK簡介2AndroidNDK是在SDK前面又加上了“原生”二字,即NativeDevelopmentKit,因此又被Google稱為“NDK”。AndroidNDK是AndroidSDK的伴隨工具,可以讓用戶用諸如C/C++原生編程語言開發(fā)Android應(yīng)用程序。原生SDK的公布可以讓開發(fā)者更加直接的接觸Android系統(tǒng)資源,并極大地提高了Android應(yīng)用程序開發(fā)的靈活性。AndroidNDK需要安裝全部AndroidSDK1.5或以上版本,到目前為止AndroidNDK已經(jīng)修訂了9版本。AndroidNDK集成了交叉編譯器,支持ARM、x86及MIPS處理器指令集、JNI接口和一些穩(wěn)定的庫文件。7.1AndroidNDK簡介49AndroidNDK是在SDK前面又加上了“原生”二字,AndroidNDK具體包括如下:ARM、x86和MIPS交叉編譯器構(gòu)建系統(tǒng)Java原生接口頭文件C庫Math庫POSIX線程最小的C++庫ZLib壓縮庫動態(tài)鏈接庫 AndroidNDK簡介Android日志庫Android像素緩沖區(qū)庫Android原生應(yīng)用APIsOpenGLES3D圖形庫OpenES原生音頻庫OpenMAXAL最小支持50AndroidNDK具體包括如下:AndroidNDK簡

7.2構(gòu)建NDK系統(tǒng)7.2.1AndroidNDK開發(fā)環(huán)境構(gòu)建7.2.2解析hello-jni例程51

7.2構(gòu)建NDK系統(tǒng)7.2.1AndroidNDAndroidNDK的構(gòu)建系統(tǒng)是基于GNUMake的,提供了頭文件、庫和交叉編譯器工具鏈,可以在MicrosoftWindows、AppleMacOSX和Linux三種操作系統(tǒng)平臺上運行。在安裝前要確保已經(jīng)最新版的AndroidSDK和升級應(yīng)用程序和環(huán)境。本書僅介紹MicrosoftWindows系統(tǒng)的NDK系統(tǒng)構(gòu)建,請按照下列步驟操作:7.2.1AndroidNDK開發(fā)環(huán)境構(gòu)建52AndroidNDK的構(gòu)建系統(tǒng)是基于GNUMake的,提第一步,在安裝完成SDK工具后,下載并安裝Cygwin。安裝完成后,要把Cygwin二進(jìn)制路徑添加到系統(tǒng)可執(zhí)行搜索路徑中。操作如下:在“系統(tǒng)屬性”界面打開環(huán)境變量對話框;在系統(tǒng)變量部分單擊New按鈕定義一個新的環(huán)境變量,將變量名設(shè)置成CYGWIN_HOME,將變量值設(shè)置成前面記下的Cygwin安裝目錄;單擊OK按鍵保存新環(huán)境變量;在環(huán)境變量對話框中的系統(tǒng)變量列表中,雙擊PATH變量,并將;%CYGWIN_HOME%\bin追加到變量值后面。7.2.1AndroidNDK開發(fā)環(huán)境構(gòu)建53第一步,在安裝完成SDK工具后,下載并安裝Cygwin。7.第二步,下載最新版AndroidNDK開發(fā)包,目前本書編寫時,最新版本是R9,請根據(jù)需要到Google的官方網(wǎng)站下載AndroidNDK。

/tools/sdk/ndk/index.html完成安裝后將AndroidNDK的二進(jìn)制路徑加到系統(tǒng)可執(zhí)行搜索路徑中,具體方法同上。第三步是配置Cygwin的NDK開發(fā)環(huán)境。修改在用戶目錄下的.bash_profile文件,在該文件的末尾處添加如下代碼:ANDROID_NDK_ROOT=/cygdrive/d/android/android-nkd-r9dExportANDROID_NDK_ROOT上述代碼說明AndroidNDK安裝的目錄,即d盤的android/android-nkd-r9d目錄下。7.2.1AndroidNDK開發(fā)環(huán)境構(gòu)建54第二步,下載最新版AndroidNDK開發(fā)包,目前本書編寫7.2.1AndroidNDK開發(fā)環(huán)境構(gòu)建所有的AndroidNDK組件都被安裝在目標(biāo)目錄下,下面介紹一些重要文件和子目錄。ndk-build:該shell腳本是AndroidNDK構(gòu)建系統(tǒng)的起始點。ndk-gdb:該shell腳本允許用GNU調(diào)試器調(diào)試原生組件。ndk-stack:該shell腳本可以幫助分析原生組件崩潰時的堆棧追蹤。build:該目錄包含可AndroidNDK構(gòu)建系統(tǒng)的所有模塊。platforms:該目錄包含了支持不同Android目標(biāo)版本的頭文件和庫文件。AndroidNDK構(gòu)建系統(tǒng)會根據(jù)具體的Android版本自動引用這些文檔。557.2.1AndroidNDK開發(fā)環(huán)境構(gòu)建所有的Andr7.2.1AndroidNDK開發(fā)環(huán)境構(gòu)建samples:該目錄包含了一些示例應(yīng)用程序,這些程序可以體現(xiàn)AndroidNDK的性能。示例項目對于學(xué)習(xí)使用AndroidNDK的特性很有幫助。sources:該目錄包含了可供開發(fā)人員導(dǎo)入到現(xiàn)有的AndroidNDK項目的一些共享模塊。toolchains:該目錄包含目前AndroidNDK支持的不同目標(biāo)機(jī)體系結(jié)構(gòu)的交叉編譯器。AndroidNDK目前支持ARM、X86和MIPS體系結(jié)構(gòu)。AndroidNDK構(gòu)建系統(tǒng)根據(jù)選定的體系結(jié)構(gòu)使用不同的交叉編譯器。567.2.1AndroidNDK開發(fā)環(huán)境構(gòu)建samples最后測試開發(fā)環(huán)境是否可以正常工作,首先雙擊Cygwin圖標(biāo),出現(xiàn)Cygwin后運行ndk-build出現(xiàn)如圖所示的運行結(jié)果,說明AndroidNDK的開發(fā)環(huán)境已經(jīng)可以正常工作了。7.2.1AndroidNDK開發(fā)環(huán)境構(gòu)建57最后測試開發(fā)環(huán)境是否可以正常工作,首先雙擊Cygwin圖標(biāo),7.2.2解析hello-jni例程首先使用import向Eclipse中導(dǎo)入工程,本機(jī)目錄為F:\android-ndk-r9d\samples\hello-jni。導(dǎo)入工程之后我們會在項目目錄下發(fā)現(xiàn)兩個比較重要的文件一個是src/com.example.hellojni/HelloJni.java文件,一個是jni/hello-jni.c文件。hello-jni.c文件定義了輸出字符串"HellofromJNI!CompiledwithABI"ABI"."的方法,而HelloJni.java文件則通過調(diào)用上述hello.c的動態(tài)鏈接庫來獲取輸出的字符串,并顯示到模擬器上。587.2.2解析hello-jni例程首先使用import向其中c文件內(nèi)容如下:10Java_com_example_hellojni_HelloJni_stringFromJNI(JNIEnv*env,jobjectthiz)11{12#ifdefined(__arm__)13#ifdefined(__ARM_ARCH_7A__)14#ifdefined(__ARM_NEON__)15#defineABI"armeabi-v7a/NEON“16#else17#defineABI"armeabi-v7a"18#endif19#else20#defineABI"armeabi"21#endif22#elifdefined(__i386__)23#defineABI"x86"24#elifdefined(__mips__)25#defineABI"mips"26#else27#defineABI"unknown"28#endif29return(*env)->NewStringUTF(env,“HellofromJNI!CompiledwithABI”ABI“.”);}這里主要的是定義了輸出字符串"HellofromJNI!CompiledwithABI"ABI"."的方法59其中c文件內(nèi)容如下:10Java_com_exa7.2.2解析hello-jni例程其中java文件內(nèi)容如下:5publicclassHelloJniextendsActivity{6publicvoidonCreate(BundlesavedInstanceState){7super.onCreate(savedInstanceState);8TextViewtv=newTextView(this);9tv.setText(stringFromJNI());10setContentView(tv);}11publicnativeStringstringFromJNI();12publicnativeStringunimplementedStringFromJNI();13static{14 System.loadLibrary("hello-jni");15}16}通過調(diào)用上述hello.c的動態(tài)鏈接庫來獲取輸出的字符串,并顯示到模擬器上。

607.2.2解析hello-jni例程其中java文件內(nèi)容如7.2.2解析hello-jni例程接著啟動Cygwin命令行輸入cdf:/android-ndk-r9d/samples/hello-jni進(jìn)入到NDK主目錄,然后編譯C代碼,其命令如下:../../ndk-build,在Cygwin中顯示如圖所示。617.2.2解析hello-jni例程接著啟動Cygwin命7.2.2解析hello-jni例程此時表明已生成所需的動態(tài)鏈接庫,接下來我們要對其進(jìn)行加載。在Eclipse的ProjectExplorer視圖中右擊HelloJni,依次選擇Androidtools、AddNativeSupport在彈出的對話框中顯示信息如圖所示。由于該項目已經(jīng)包含了一個原生項目,所以庫名可以保持不變,點擊finish即可完成加載。在Android模擬器上運行該項目,其運行效果如下:627.2.2解析hello-jni例程此時表明已生成所需的動7.3NDK開發(fā)過程詳解7.3.1中間件概念7.3.2Android系統(tǒng)的中間件7.3.3使用C/C++實現(xiàn)本地方法7.3.4依賴關(guān)系建立7.3.5NDK程序的鏈接與運行637.3NDK開發(fā)過程詳解7.3.1中間件概念177.3NDK開發(fā)過程詳解AndroidNDK構(gòu)建系統(tǒng)所提供的不同功能,例如建立一個共享庫建立多種共享庫建立靜態(tài)庫利用共享庫通用模塊在多種NDK項目間共享模塊使用預(yù)建庫建立獨立的可執(zhí)行文件其他構(gòu)建系統(tǒng)變量和宏定義新變量和條件操作647.3NDK開發(fā)過程詳解AndroidNDK構(gòu)建系統(tǒng)所提在進(jìn)行NDK開發(fā)時,一般需要同時建立Android工程和C/C++工程,然后使用NDK編譯C/C++工程,形成可以被調(diào)用的共享庫,最后共享庫文件會被拷貝到Android工程中,并被打包到apk文件中。其開發(fā)過程可分為以下幾步:設(shè)計JNI接口用C/C++實現(xiàn)本地的方法編譯文件的實現(xiàn)生成動態(tài)連接庫。7.3NDK開發(fā)過程詳解65在進(jìn)行NDK開發(fā)時,一般需要同時建立Android工程和C/中間件(Middleware)是處于操作系統(tǒng)和應(yīng)用程序之間的軟件,它包括一組服務(wù),以便于運行在一臺或多臺機(jī)器上的多個軟件通過網(wǎng)絡(luò)進(jìn)行交互。該架構(gòu)通常用于支持分布式應(yīng)用程序并簡化其復(fù)雜度,它包括web服務(wù)器、事務(wù)監(jiān)控器和消息隊列軟件。中間件能夠屏蔽操作系統(tǒng)和網(wǎng)絡(luò)協(xié)議的差異,為應(yīng)用程序提供多種通訊機(jī)制;并提供相應(yīng)的平臺以滿足不同領(lǐng)域的需要。中間件帶給應(yīng)用系統(tǒng)的,不只是開發(fā)的簡便、開發(fā)周期的縮短,也減少了系統(tǒng)的維護(hù)、運行和管理的工作量,還減少了計算機(jī)總體費用的投入。7.3.1中間件概念66中間件(Middleware)是處于操作系統(tǒng)和應(yīng)用程序之間的中間件是操作系統(tǒng)與應(yīng)用程序的溝通橋梁,并分為兩層:函數(shù)層(Library)和虛擬機(jī)(VirtualMachine)。應(yīng)用程序用Java語言開發(fā),操作系統(tǒng)代碼則是C代碼,它們之間的通信需要用JNI來實現(xiàn)。JNI一般有以下一些應(yīng)用場景:高性能,在一些情況下因為處理運算量非常大,為了獲取高性能,直接使用java是不能勝任的,如:一些圖形的處理;調(diào)用一些硬件的驅(qū)動或者一些軟件的驅(qū)動,比如調(diào)用一些外部系統(tǒng)接口的驅(qū)動,如:讀卡器的驅(qū)動,OCI驅(qū)動;需要使用大內(nèi)存,遠(yuǎn)遠(yuǎn)超過VM所能分配的內(nèi)存,如:進(jìn)程內(nèi)Cache;調(diào)用C或者操作系統(tǒng)提供的服務(wù),如:java調(diào)用搜索服務(wù),搜索是由C/C++實現(xiàn)的。7.3.2Android系統(tǒng)的中間件67中間件是操作系統(tǒng)與應(yīng)用程序的溝通橋梁,并分為兩層:函數(shù)層(L通常JNI的使用自上至下有4層,本地庫,JNI庫,聲明本地接口的Java類,Java調(diào)用者,JNI在Android層次結(jié)構(gòu)中的作用如圖所示。7.3.2Android系統(tǒng)的中間件68通常JNI的使用自上至下有4層,本地庫,JNI庫,聲明本地接實現(xiàn)JNI需要在C++代碼中實現(xiàn)JNI的各種方法,并注冊到系統(tǒng)中,另外還要在Java源代碼中聲明。[例7-2]實例實現(xiàn)JNI接口的設(shè)計。在此之前我們需要將將NDK與Cygwin關(guān)聯(lián)起來,即打開<Cygwin安裝目錄>\home\Administrator\.bash_profile文件(本文F:\cygwin\home\mwy\.bash_profile,在文件中加入如下代碼:1 NDK_ROOT=/cygdrive/f/android-ndk-r9d/2 exportNDK_ROOT3 PATH+=:$NDK_ROOT4 exportPATH7.3.2Android系統(tǒng)的中間件69實現(xiàn)JNI需要在C++代碼中實現(xiàn)JNI的各種方法,并注冊到系接口設(shè)計過程如下:在NDK安裝目錄下新建文件夾apps,在apps下新建目錄san-angeles(這個名字可以自己任意取),并Eclipse中新建工程SanAngeles。建立工程之后需要創(chuàng)建并編寫JNI類代碼,用來聲明要調(diào)用的本地方法,關(guān)鍵字native。此時在Eclipse中新建名為JNITest的類。7.3.2Android系統(tǒng)的中間件70接口設(shè)計過程如下:7.3.2Android系統(tǒng)的中間件24其代碼如下:1 packagecom.example.SanAngeles;2 publicclassJNITest{3 privatestaticnativevoidnativeInit();4 privatestaticnativevoidnativeResize(intw,inth);5 privatestaticnativevoidnativeRender();6privatestaticnativevoidnativeDone();7 }7.3.2Android系統(tǒng)的中間件71為調(diào)用內(nèi)核代碼提供的接口其代碼如下:7.3.2Android系統(tǒng)的中間件25為調(diào)用編譯Java文件,并生成相應(yīng)的頭文件我們需要將新建的JNItest.java文件復(fù)制到工程目錄的bin目錄下并用命令行編譯。首先進(jìn)入NDK主目錄,接著輸入

>javacJNITest.java即可生成JNItest.class文件。將此文件復(fù)制到F:\android-ndk-r9d\apps\san-angeles\project\bin\classes\com\example\SanAngeles中替換原有文件;從命令行進(jìn)入bin/classes目錄,輸入

>javah–jnicom_example_angles_JNITest生成com_example_angles_JNITest.h的C頭文件,最后在此工程目錄下(即project目錄下)創(chuàng)建jni文件夾,并將生成的頭文件復(fù)制到此處。這個頭文件主要是來處理C/C++和Java中一些定義的差別。而其中的JNIEXPORT和JNICALL都是JNI的關(guān)鍵字,表示函數(shù)式要被JNI調(diào)用的。7.3.2Android系統(tǒng)的中間件72編譯Java文件,并生成相應(yīng)的頭文件7.3.2Androi編譯Java文件,并生成相應(yīng)的頭文件其內(nèi)容如下:7.3.2Android系統(tǒng)的中間件1 #include<jni.h>2 /*Headerforclasscom_example_angles_JNITest*/3 #ifndef_Included_com_example_angles_JNITest4 #define_Included_com_example_angles_JNITest5 #ifdef__cplusplus6 extern"C"{7 #endif8 /*9 *Class:com_example_angles_JNITest10 *Method:nativeInit11 *Signature:()V12 */13 JNIEXPORTvoidJNICALLJava_com_example_angles_JNITest_nativeInit(JNIEnv*,jclass);14 /*15 *Class:com_example_angles_JNITest16 *Method:nativeResize17 *Signature:(II)V73編譯Java文件,并生成相應(yīng)的頭文件7.3.2Androi7.3.2Android系統(tǒng)的中間件18 */19 JNIEXPORTvoidJNICALLJava_com_example_angles_JNITest_nativeResize(JNIEnv*,jclass,jint,jint);20 /*21 *Class:com_example_angles_JNITest22 *Method:nativeRender23 *Signature:()V24 */25 JNIEXPORTvoidJNICALLJava_com_example_angles_JNITest_nativeRender(JNIEnv*,jclass);26 /*27 *Class:com_example_angles_JNITest28 *Method:nativeDone29 *Signature:()V30 */31 JNIEXPORTvoidJNICALLJava_com_example_angles_JNITest_nativeDone(JNIEnv*,jclass);32 #ifdef__cplusplus33 }34 #endif35 #endif這個頭文件主要是來處理C/C++和Java中一些定義的差別。而其中的JNIEXPORT和JNICALL都是JNI的關(guān)鍵字,表示函數(shù)式要被JNI調(diào)用的747.3.2Android系統(tǒng)的中間件18 */這個頭文件在jni目錄下新建app-android.c文件并編寫其代碼,這里我們重點介紹這幾個原生方法的實現(xiàn):Java_com_example_angles_JNITest_nativeInit這個命名必須遵循“函數(shù)名=Java_開頭+包名和類名+接口名”這一規(guī)律。這個名字要是錯了就無法被調(diào)用到。7.3.3使用C/C++實現(xiàn)本地方法1voidJava_com_example_angles_JNITest_nativeInit(JNIEnv*env){2 ImportGLInit();3 appInit();4 gAppAlive=1;5 sDemoStopped=0;6 sTimeOffsetInit=0;}75在jni目錄下新建app-android.c文件并編寫其代碼在上述方法中有兩個常見的參數(shù),其中一個參數(shù)JNIEnv是指向可用JNI函數(shù)表的接口指針;另一個參數(shù)jobject是Java引用。下面將對這兩個參數(shù)做詳細(xì)介紹。JNIEnv接口指針示意圖如下:7.3.3使用C/C++實現(xiàn)本地方法76在上述方法中有兩個常見的參數(shù),其中一個參數(shù)JNIEnv是指向JNIEnv接口指針JNIEnv接口指針,指向一個函數(shù)表,函數(shù)表中的每一個入口指向一個JNI函數(shù)。JNIEnv是一個與線程相關(guān)的變量,不同線程的JNIEnv彼此獨立。在C與C++中使用JNIEnv*env分別如下:C:(*env)->方法名(env,參數(shù)列表)C++:env->方法名(參數(shù)列表)參數(shù)jobject代表的是一個原生實例的方法,它與類實例相關(guān),它們只能在類實例中調(diào)用,通過第二個參數(shù)獲取實例引用。在原生代碼不僅可以通過實例方法實現(xiàn)開可以通過靜態(tài)方法實現(xiàn),與實例方法不同的是第二參數(shù)為jclass值類型的,而且它沒有與實例綁定,可以在靜態(tài)上下文直接引用。7.3.3使用C/C++實現(xiàn)本地方法77JNIEnv接口指針7.3.3使用C/C++實現(xiàn)本地方法3通過C語言來實現(xiàn)OpenGL編程,來說明依賴關(guān)系的建立。具體可參見工程中其余的代碼。7.3.4依賴關(guān)系建立78通過C語言來實現(xiàn)OpenGL編程,來說明依賴關(guān)系的建立。具體AndroidNDK構(gòu)建系統(tǒng)依賴另外二個文件:Android.mk和Application.mk,這兩個文件應(yīng)該作為NDK項目的一部分由開發(fā)人員提供,下面我們將重點介紹。Android.mk文件:Android.mk是向AndroidNDK系統(tǒng)項目中GUNMakefile文件,用于描述實現(xiàn)嵌入的必備信息,因此也是每個NDK項目的必備組件。針對上述的工程,需添加的Android.mk的文件內(nèi)容如下。7.3.4依賴關(guān)系建立1. LOCAL_PATH:=$(callmy-dir)2. include$(CLEAR_VARS)3. LOCAL_MODULE:=hello-jni4. LOCAL_SRC_FILES:=hello-jni.c5. include$(BUILD_SHARED_LIBRARY)79AndroidNDK構(gòu)建系統(tǒng)依賴另外二個文件:Androi7.3.4依賴關(guān)系建立1. LOCAL_PATH:=$(callmy-dir)2. include$(CLEAR_VARS)3. LOCAL_MODULE:=hello-jni4. LOCAL_SRC_FILES:=hello-jni.c5. include$(BUILD_SHARED_LIBRARY)Android系統(tǒng)用LOCAL_PATH來表示需要編譯的C/C++代碼所在目錄,my-dir是AndroidNDK編譯系統(tǒng)提供的宏功能,通過調(diào)用該宏功能返回當(dāng)前目錄的位置。Android系統(tǒng)將CLEAR_VARS變量設(shè)置為腳本文件cl

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論