http://www.eoeandroid.com/thread-2223-1-5.html
1. NDK綜述,通過一篇比較直觀的文章,讓大家快速了解NDK
http://www.google.cn/search?hl=zh-CN&client=aff-cs-maxthon&hs=I09&newwindow=1&q=Android+NDK&aq=f&oq=
2. NDK 中有五篇doc 的文章,這些是我們NDK最標(biāo)準(zhǔn)的開發(fā)文檔
我們要把這六篇翻譯成我們最熟悉的中文
http://developer.android.com/sdk/ndk/1.5_r1/index.html
3. NDK 的環(huán)境、配置安裝,hello NDK 的運(yùn)行
參考帖子:
http://www.eoeandroid.com/viewthread.php?tid=1219&highlight=ndk
4. NDK的實(shí)戰(zhàn)
5. NDK 與 普通的Java開發(fā)的效率對比
http://www.google.cn/search?hl=zh-CN&client=aff-cs-maxthon&hs=I09&newwindow=1&q=Android+NDK&aq=f&oq=
2. NDK 中有五篇doc 的文章,這些是我們NDK最標(biāo)準(zhǔn)的開發(fā)文檔
我們要把這六篇翻譯成我們最熟悉的中文
http://developer.android.com/sdk/ndk/1.5_r1/index.html
3. NDK 的環(huán)境、配置安裝,hello NDK 的運(yùn)行
參考帖子:
http://www.eoeandroid.com/viewthread.php?tid=1219&highlight=ndk
4. NDK的實(shí)戰(zhàn)
5. NDK 與 普通的Java開發(fā)的效率對比
http://www.eoeandroid.com/forum.php?mod=viewthread&tid=1219
標(biāo) 題: HWOTO install and setup Android NDK for Windows
[size=1.05em]發(fā)布日期: 2009-06-27 18:00
原文鏈接: http://emck.avaw.com/?p=250作 者: Emck
說 明: 此文檔嚴(yán)格遵循GPL協(xié)議,轉(zhuǎn)貼請保持此文檔的完整性!
[size=1.05em]1. 下載Android 1.5 NDK, Release 1 For Windows 并解壓到D:\android-ndk-1.5_r1
[size=1.05em]2.下載Cygwin, 執(zhí)行setup.exe并開始安裝(根據(jù)網(wǎng)絡(luò)速度快慢而定, 預(yù)計安裝需要20分鐘左右)
注意:1. 選擇臺灣的http站點(diǎn),速度會快很多; 2.開發(fā)選項里必須勾選gcc和make,否則后期無法編譯
[size=1.05em]3.執(zhí)行桌面圖標(biāo)Cygwin,出現(xiàn)linux shell提示符后, 修改當(dāng)前目錄(/home/username)下.bash_profile文件, 加入如下內(nèi)容在文件尾部
ANDROID_NDK_ROOT=/cygdrive/d/android-ndk-1.5_r1
export ANDROID_NDK_ROOT
[size=1.05em]4.退出Cygwin,重新進(jìn)入,執(zhí)行以下命令
cd $ANDROID_NDK_ROOT
build/host-setup.sh
一切順利的話會提示設(shè)置成功, 如果出錯, 則檢查錯誤并修復(fù)
[size=1.05em]5.編譯sample hello-jni
進(jìn)入Cygwin
cd $ANDROID_NDK_ROOT
make APP=hello-jni
一切順利則會生成libhello-jni.so文件在 $ANDROID_NDK_ROOT/apps/hello-jni/project/libs/armeabi目錄下
[size=1.05em]6.啟動預(yù)先配置好的Eclipse + ADT環(huán)境,創(chuàng)建一個Android Project,選擇Create project form existring source
Location = D:\android-ndk-1.5_r1\apps\hello-jni\project, 直接確認(rèn)即可開始編譯并生成apk文件
[size=1.05em]7.運(yùn)行這個Project,及可看到效果.
[size=1.05em]發(fā)布日期: 2009-06-27 18:00
原文鏈接: http://emck.avaw.com/?p=250作 者: Emck
說 明: 此文檔嚴(yán)格遵循GPL協(xié)議,轉(zhuǎn)貼請保持此文檔的完整性!
[size=1.05em]1. 下載Android 1.5 NDK, Release 1 For Windows 并解壓到D:\android-ndk-1.5_r1
[size=1.05em]2.下載Cygwin, 執(zhí)行setup.exe并開始安裝(根據(jù)網(wǎng)絡(luò)速度快慢而定, 預(yù)計安裝需要20分鐘左右)
注意:1. 選擇臺灣的http站點(diǎn),速度會快很多; 2.開發(fā)選項里必須勾選gcc和make,否則后期無法編譯
[size=1.05em]3.執(zhí)行桌面圖標(biāo)Cygwin,出現(xiàn)linux shell提示符后, 修改當(dāng)前目錄(/home/username)下.bash_profile文件, 加入如下內(nèi)容在文件尾部
ANDROID_NDK_ROOT=/cygdrive/d/android-ndk-1.5_r1
export ANDROID_NDK_ROOT
[size=1.05em]4.退出Cygwin,重新進(jìn)入,執(zhí)行以下命令
cd $ANDROID_NDK_ROOT
build/host-setup.sh
一切順利的話會提示設(shè)置成功, 如果出錯, 則檢查錯誤并修復(fù)
[size=1.05em]5.編譯sample hello-jni
進(jìn)入Cygwin
cd $ANDROID_NDK_ROOT
make APP=hello-jni
一切順利則會生成libhello-jni.so文件在 $ANDROID_NDK_ROOT/apps/hello-jni/project/libs/armeabi目錄下
[size=1.05em]6.啟動預(yù)先配置好的Eclipse + ADT環(huán)境,創(chuàng)建一個Android Project,選擇Create project form existring source
Location = D:\android-ndk-1.5_r1\apps\hello-jni\project, 直接確認(rèn)即可開始編譯并生成apk文件
[size=1.05em]7.運(yùn)行這個Project,及可看到效果.
http://www.eoeandroid.com/thread-52127-1-3.html
這是我轉(zhuǎn)的文章,是篇外文翻譯,將介紹如何學(xué)習(xí)安裝 Android NDK 并開始使用它。在這一教程結(jié)束后,將創(chuàng)建你自己的項目,從 Java 代碼簡單地調(diào)用原生C 語言代碼。
教程細(xì)節(jié)
技術(shù):Android SDK、NDK、C 語言
難度:進(jìn)階
預(yù)計完成時間:60-90 分鐘(⊙﹏⊙b汗,還是挺長時間的)
先決經(jīng)驗(yàn):
在開始之前,需要先花點(diǎn)時間了解一下這一教程的難度。它的標(biāo)記是“進(jìn)階”。之所以標(biāo)為“進(jìn)階”是因?yàn)樽髡呦胍_保你符合以下要求:
1、有Java和C語言經(jīng)驗(yàn)。
2、能適應(yīng)命令行操作。
3、知道如何了解你的 Cygwin、awk 和其他工具的版本。
4、能適應(yīng) Android Development。
5、有一個有效的 Android 開發(fā)環(huán)境(本文撰寫時,筆者使用的是 Android 2.2)
5、使用 Eclipse 或者可以將 Eclipse 的指導(dǎo)步驟輕松應(yīng)用于自己的 IDE 上。
6、就算并不滿足這些條件,當(dāng)然也歡迎你閱讀這一教程,不過可能在某些步驟遇到困難。
如果滿足了以上條件這些困難就會輕易解除。也就是說,即使認(rèn)為自己是個移動開發(fā)老手,使用 NDK 依然很容易碰到困難和麻煩。請注意可能要自行排查故障才能讓一切正常運(yùn)轉(zhuǎn)于你的開發(fā)系統(tǒng)中。
本教程提供完整的樣例項目的開源代碼。(我么有找到下載的東東)
何時使用 NDK 的說明
好,正在閱讀這篇教程的你,也許已經(jīng)在考慮在你的 Android 項目中使用 NDK 了。不過,作者想要花點(diǎn)時間討論一下 NDK 為什么那么重要、何時該使用它,以及——同等重要的,何時不該使用它。
總的來說,只有當(dāng)應(yīng)用程序真的是個處理器殺手的時候,你才需要使用 NDK。也就是說,你設(shè)計的算法要利用 DalvikVM 中所有的處理器資源,而且原生運(yùn)行較為有利。還有,別忘了在 Android 2.2 中,JIT 編譯器會提高類似代碼的效率。
另一個使用 NDK 的原因是方便移植。如果在現(xiàn)有的應(yīng)用程序中有大量的 C 語言代碼,那么使用 NDK 不僅可以加速你項目的開發(fā)進(jìn)程,也能在你的 Android 和非 Android 項目中保持修改的同步。這一點(diǎn)對于那些為其他平臺而寫的 OpenGL ES 應(yīng)用程序來說尤為如此。
別以為只要用了原生代碼就能提高應(yīng)用程序的效率。Java 與原生C 語言之間的轉(zhuǎn)換會增加一些資源開銷,因此只有你有一些集中消耗處理器資源的任務(wù)時才真正有必要這么做。
第 0 步:下載工具
好了,現(xiàn)在就開始吧!你需要下載 NDK。先來開始下載,因?yàn)樵谙螺d的過程中你可以檢查一下,確保所需要用到的其余工具的版本都正確。
從 Android 網(wǎng)站下載適合你的操作系統(tǒng)的 NDK。
現(xiàn)在,對照下列檢查你的工具版本:
1、如果在 Windows 下,Cygwin 1.7 或更高版本
2、將 awk 升級到最新版本(我們使用的是 20070501)
3、GNU Make 3.81 或更高版本(我們使用的是 3.81)
如果其中任何一個的版本太舊,請在繼續(xù)之前先升級。
第 1 步:安裝 NDK
既然 NDK 已經(jīng)下載完成(沒錯吧?),你就需要解壓縮它。解壓后將它放入合適的目錄中。要把它放在和 Android SDK 相同的目錄下。記住你把它放在哪里了。
現(xiàn)在,你也許想要在路徑設(shè)置中添加 NDK 工具。如果你在 Mac 或 Linux 下,你可以用你的原生路徑設(shè)置來完成。如果你在 Windows 下的 Cygwin,你就需要設(shè)置 Cygwin 的路徑設(shè)置。
第 2 步:創(chuàng)建項目
創(chuàng)建一個常規(guī)的 Android 項目。為了避免日后的問題,你項目的路徑必須不包含空格。作者的項目有個叫做“com.mamlambo.sample.ndk1”的包,帶有一個叫做 “AndroidNDK1SampleActivity”的默認(rèn) Activity——你之后還會看到它們。
在這個項目的頂層創(chuàng)建一個叫做“jni”的目錄——這是你放置原生代碼的地方。如果你很熟悉 JNI,那你就會知道 Android NDK 很大程度上基于 JNI 的概念——它本質(zhì)上是個只有有限的 C 語言編譯頭文件的 JNI。
第 3 步:添加一些 C 語言代碼
現(xiàn)在,在 jni 文件夾中,創(chuàng)建一個叫做 native.c 的文件。一開始將以下 C 語言代碼寫入該文件,我們以后再添加另一個函數(shù):
復(fù)制代碼 這個函數(shù)實(shí)際上非常淺顯。它獲取一個 Java 對象的字符串參數(shù),將它轉(zhuǎn)換為 C-string,然后將它寫入到 LogCat 中。
不過該函數(shù)的名字很重要。它遵循了以“Java”的特定字樣開頭,后面跟著包名稱,然后類名稱,然后方法名稱,和 Java 中定義的一樣。每一部分都由一根下劃線隔開,而不是點(diǎn)。
該函數(shù)的頭兩個參數(shù)也很重要。第一個參數(shù)是 JNI 環(huán)境,它與 helper 函數(shù)會被頻繁調(diào)用。第二個參數(shù)是該函數(shù)所屬的Java 對象。
第 4 步:從 Java 中調(diào)用原生代碼
既然你已經(jīng)寫好了原生代碼,讓我們回頭看看 Java 這邊。在默認(rèn)的 Activity 中,按照你的喜好創(chuàng)建一個按鈕,并添加一個按鈕處理器。從按鈕處理器中,對 helloLog 作調(diào)用:
復(fù)制代碼 然后你必須在 Java 這邊添加函數(shù)聲明。在你的 Activity 類中添加如下聲明:
復(fù)制代碼 它告訴編譯和鏈接系統(tǒng)該方法將在原生代碼中實(shí)現(xiàn)。
最后,你需要加載原生代碼最終編譯到的庫。在 Activity 類中添加如下的靜態(tài)初始化程序來根據(jù)名稱加載庫(庫的名字隨你決定,在下一步還會用到):
復(fù)制代碼第 5 步:添加原生代碼的 Make 文件
在 jni 文件夾中,現(xiàn)在你需要添加在編譯中要用到的 makefile。該文件必須以“Android.mk”命名,如果你之前命名的文件為 native.c,庫為 ndk1,那么 Android.mk 的內(nèi)容就應(yīng)該是這樣:
復(fù)制代碼第 6 步:編譯原生代碼
既然你的原生代碼已完成,make 文件也已就緒,是時候編譯原生代碼了。在命令行下(Windows 用戶在 Cygwin 下),你需要在你的項目的根目錄下運(yùn)行 ndk-build 命令。ndk-build 工具就在 NDK 工具目錄中。將它添加到我們的路徑中是最方便的辦法。
在之后的編譯中,如果你使用“ndk-build clean”命令,那么你可以確保所有的東西都被重新編譯了。
第 7 步:運(yùn)行代碼
現(xiàn)在你已準(zhǔn)備妥當(dāng)可以運(yùn)行代碼了。在你最喜歡的模擬器或者手持設(shè)備中載入該項目,查看 LogCat,然后點(diǎn)擊按鈕。
可能有兩件事情會發(fā)生。首先,它可能正常工作了。這樣的話,恭喜你!不過你可能還是想要繼續(xù)閱讀下去。
你也可能在 LogCat 中得到類似“Could not execute method of activity”這樣的錯誤。這很正常。這只是說明你漏掉了某個步驟罷了。用 Eclipse 很容易發(fā)生這種情況。通常,Eclipse 被設(shè)置為自動重編譯。
如果它不知道有東西被修改了,它就不會自動重編譯和重鏈接。在本例中,Eclipse 不知道你編譯了原生代碼。所以,“清除(cleaning)”該項目(在 Eclipse 工具欄中點(diǎn)擊項目(Project)->清除(Clean)),強(qiáng)制 Eclipse 重編譯。
第 8 步:添加另一個原生函數(shù)
接下來的函數(shù)將不僅演示返回值的能力,還會演示返回例如字符串這樣的對象的能力。在 native.c 中添加如下函數(shù):
復(fù)制代碼 為了正常編譯,你會需要添加一個 include stdio.h 的聲明。而且,為了響應(yīng)這個新的原生函數(shù),請在你的 Activity Java 類中添加如下聲明:
復(fù)制代碼 你現(xiàn)在可以隨意設(shè)定其功能。我們使用如下兩個調(diào)用和輸出:
復(fù)制代碼 回到 C 語言函數(shù)中,你會注意到我們做了許多事情。首先,我們在使用 malloc() 函數(shù)中的 sprintf() 調(diào)用時需要創(chuàng)建一個緩沖器(buffer)。如果你不會忘記通過使用 free() 函數(shù)清理結(jié)果,那么這就很合理了。
然后,為了傳回結(jié)果,你可以使用一個叫作 NewStringUTF() 的 JNI helper 函數(shù)。該函數(shù)基本上就是獲取一個 C 語言字符串,以之創(chuàng)建一個新的 Java 對象。這個新的字符串對象就可以在之后作為結(jié)果返回,你就可以在 Java 類中將它作為一個常規(guī) Java 字符串對象使用了。
指令集、兼容性
Android NDK 需要 Android SDK 1.5 或更高版本。在新版本的 NDK 中,有些新的頭文件可用于擴(kuò)大對某些 API 的訪問——特別是 OpenGL ES 庫。
不過,那些都不是我們要談?wù)摰募嫒菪浴_@是原生代碼,在使用時由處理器構(gòu)架編譯。因此,你要問自己的一個問題會是它支持何種處理器構(gòu)架?在目前的 NDK 中(在本文撰寫時)它只支持 ARMv5TE 和 ARMv7-A 指令集。默認(rèn)設(shè)置下,目標(biāo)架構(gòu)被設(shè)置為 ARMv5TE,它可以在使用 ARM 芯片的 Android 設(shè)備上運(yùn)行。
它預(yù)計未來將支持其他指令集(其中提到了 x86)。這其中有很有意思的潛在狀況:NDK 解決方案無法適用于所有的設(shè)備。例如,市面上有使用 x86 指令集的英特爾(Intel)Atom 處理器的 Android 平板設(shè)備。
那么 NDK 在模擬器上如何呢?模擬器運(yùn)行的是真正的虛擬機(jī),包括完整的處理器虛擬。沒錯,這意味著在虛擬機(jī)中運(yùn)行 Java 就等于是在虛擬機(jī)中運(yùn)行了一個虛擬機(jī)。
總結(jié)
成果如何?你裝上了 Android NDK,最終完成了部分使用原生 C 語言代碼的功能完善、正常運(yùn)行的應(yīng)用程序了嗎?我們希望如此。在這一過程中有許多潛在的“出問題啦!”的可能,不過從某些方面來看,這些都是值得的。
教程細(xì)節(jié)
技術(shù):Android SDK、NDK、C 語言
難度:進(jìn)階
預(yù)計完成時間:60-90 分鐘(⊙﹏⊙b汗,還是挺長時間的)
先決經(jīng)驗(yàn):
在開始之前,需要先花點(diǎn)時間了解一下這一教程的難度。它的標(biāo)記是“進(jìn)階”。之所以標(biāo)為“進(jìn)階”是因?yàn)樽髡呦胍_保你符合以下要求:
1、有Java和C語言經(jīng)驗(yàn)。
2、能適應(yīng)命令行操作。
3、知道如何了解你的 Cygwin、awk 和其他工具的版本。
4、能適應(yīng) Android Development。
5、有一個有效的 Android 開發(fā)環(huán)境(本文撰寫時,筆者使用的是 Android 2.2)
5、使用 Eclipse 或者可以將 Eclipse 的指導(dǎo)步驟輕松應(yīng)用于自己的 IDE 上。
6、就算并不滿足這些條件,當(dāng)然也歡迎你閱讀這一教程,不過可能在某些步驟遇到困難。
如果滿足了以上條件這些困難就會輕易解除。也就是說,即使認(rèn)為自己是個移動開發(fā)老手,使用 NDK 依然很容易碰到困難和麻煩。請注意可能要自行排查故障才能讓一切正常運(yùn)轉(zhuǎn)于你的開發(fā)系統(tǒng)中。
本教程提供完整的樣例項目的開源代碼。(我么有找到下載的東東)
何時使用 NDK 的說明
好,正在閱讀這篇教程的你,也許已經(jīng)在考慮在你的 Android 項目中使用 NDK 了。不過,作者想要花點(diǎn)時間討論一下 NDK 為什么那么重要、何時該使用它,以及——同等重要的,何時不該使用它。
總的來說,只有當(dāng)應(yīng)用程序真的是個處理器殺手的時候,你才需要使用 NDK。也就是說,你設(shè)計的算法要利用 DalvikVM 中所有的處理器資源,而且原生運(yùn)行較為有利。還有,別忘了在 Android 2.2 中,JIT 編譯器會提高類似代碼的效率。
另一個使用 NDK 的原因是方便移植。如果在現(xiàn)有的應(yīng)用程序中有大量的 C 語言代碼,那么使用 NDK 不僅可以加速你項目的開發(fā)進(jìn)程,也能在你的 Android 和非 Android 項目中保持修改的同步。這一點(diǎn)對于那些為其他平臺而寫的 OpenGL ES 應(yīng)用程序來說尤為如此。
別以為只要用了原生代碼就能提高應(yīng)用程序的效率。Java 與原生C 語言之間的轉(zhuǎn)換會增加一些資源開銷,因此只有你有一些集中消耗處理器資源的任務(wù)時才真正有必要這么做。
第 0 步:下載工具
好了,現(xiàn)在就開始吧!你需要下載 NDK。先來開始下載,因?yàn)樵谙螺d的過程中你可以檢查一下,確保所需要用到的其余工具的版本都正確。
從 Android 網(wǎng)站下載適合你的操作系統(tǒng)的 NDK。
現(xiàn)在,對照下列檢查你的工具版本:
1、如果在 Windows 下,Cygwin 1.7 或更高版本
2、將 awk 升級到最新版本(我們使用的是 20070501)
3、GNU Make 3.81 或更高版本(我們使用的是 3.81)
如果其中任何一個的版本太舊,請在繼續(xù)之前先升級。
第 1 步:安裝 NDK
既然 NDK 已經(jīng)下載完成(沒錯吧?),你就需要解壓縮它。解壓后將它放入合適的目錄中。要把它放在和 Android SDK 相同的目錄下。記住你把它放在哪里了。
現(xiàn)在,你也許想要在路徑設(shè)置中添加 NDK 工具。如果你在 Mac 或 Linux 下,你可以用你的原生路徑設(shè)置來完成。如果你在 Windows 下的 Cygwin,你就需要設(shè)置 Cygwin 的路徑設(shè)置。
第 2 步:創(chuàng)建項目
創(chuàng)建一個常規(guī)的 Android 項目。為了避免日后的問題,你項目的路徑必須不包含空格。作者的項目有個叫做“com.mamlambo.sample.ndk1”的包,帶有一個叫做 “AndroidNDK1SampleActivity”的默認(rèn) Activity——你之后還會看到它們。
在這個項目的頂層創(chuàng)建一個叫做“jni”的目錄——這是你放置原生代碼的地方。如果你很熟悉 JNI,那你就會知道 Android NDK 很大程度上基于 JNI 的概念——它本質(zhì)上是個只有有限的 C 語言編譯頭文件的 JNI。
第 3 步:添加一些 C 語言代碼
現(xiàn)在,在 jni 文件夾中,創(chuàng)建一個叫做 native.c 的文件。一開始將以下 C 語言代碼寫入該文件,我們以后再添加另一個函數(shù):
- #include
- #include
- #include
- #define DEBUG_TAG "NDK_AndroidNDK1SampleActivity"
- void Java_com_mamlambo_sample_ndk1_AndroidNDK1SampleActivity_helloLog(JNIEnv * env, jobject this, jstring logThis)
- {
- jboolean isCopy;
- const char * szLogThis = (*env)->GetStringUTFChars(env, logThis, &isCopy);
- __android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK:LC: [%s]", szLogThis);
- (*env)->ReleaseStringUTFChars(env, logThis, szLogThis);
- }
不過該函數(shù)的名字很重要。它遵循了以“Java”的特定字樣開頭,后面跟著包名稱,然后類名稱,然后方法名稱,和 Java 中定義的一樣。每一部分都由一根下劃線隔開,而不是點(diǎn)。
該函數(shù)的頭兩個參數(shù)也很重要。第一個參數(shù)是 JNI 環(huán)境,它與 helper 函數(shù)會被頻繁調(diào)用。第二個參數(shù)是該函數(shù)所屬的Java 對象。
第 4 步:從 Java 中調(diào)用原生代碼
既然你已經(jīng)寫好了原生代碼,讓我們回頭看看 Java 這邊。在默認(rèn)的 Activity 中,按照你的喜好創(chuàng)建一個按鈕,并添加一個按鈕處理器。從按鈕處理器中,對 helloLog 作調(diào)用:
- helloLog("This will log to LogCat via the native call.");
- private native void helloLog(String logThis);
最后,你需要加載原生代碼最終編譯到的庫。在 Activity 類中添加如下的靜態(tài)初始化程序來根據(jù)名稱加載庫(庫的名字隨你決定,在下一步還會用到):
- static {
- System.loadLibrary("ndk1");
- }
在 jni 文件夾中,現(xiàn)在你需要添加在編譯中要用到的 makefile。該文件必須以“Android.mk”命名,如果你之前命名的文件為 native.c,庫為 ndk1,那么 Android.mk 的內(nèi)容就應(yīng)該是這樣:
- LOCAL_PATH := $(call my-dir)
- include $(CLEAR_VARS)
- LOCAL_LDLIBS := -llog
- LOCAL_MODULE := ndk1
- LOCAL_SRC_FILES := native.c
- include $(BUILD_SHARED_LIBRARY)
既然你的原生代碼已完成,make 文件也已就緒,是時候編譯原生代碼了。在命令行下(Windows 用戶在 Cygwin 下),你需要在你的項目的根目錄下運(yùn)行 ndk-build 命令。ndk-build 工具就在 NDK 工具目錄中。將它添加到我們的路徑中是最方便的辦法。

在之后的編譯中,如果你使用“ndk-build clean”命令,那么你可以確保所有的東西都被重新編譯了。
第 7 步:運(yùn)行代碼
現(xiàn)在你已準(zhǔn)備妥當(dāng)可以運(yùn)行代碼了。在你最喜歡的模擬器或者手持設(shè)備中載入該項目,查看 LogCat,然后點(diǎn)擊按鈕。
可能有兩件事情會發(fā)生。首先,它可能正常工作了。這樣的話,恭喜你!不過你可能還是想要繼續(xù)閱讀下去。
你也可能在 LogCat 中得到類似“Could not execute method of activity”這樣的錯誤。這很正常。這只是說明你漏掉了某個步驟罷了。用 Eclipse 很容易發(fā)生這種情況。通常,Eclipse 被設(shè)置為自動重編譯。
如果它不知道有東西被修改了,它就不會自動重編譯和重鏈接。在本例中,Eclipse 不知道你編譯了原生代碼。所以,“清除(cleaning)”該項目(在 Eclipse 工具欄中點(diǎn)擊項目(Project)->清除(Clean)),強(qiáng)制 Eclipse 重編譯。
第 8 步:添加另一個原生函數(shù)
接下來的函數(shù)將不僅演示返回值的能力,還會演示返回例如字符串這樣的對象的能力。在 native.c 中添加如下函數(shù):
- jstring Java_com_mamlambo_sample_ndk1_AndroidNDK1SampleActivity_getString(JNIEnv * env, jobject this, jint value1, jint value2)
- {
- char *szFormat = "The sum of the two numbers is: %i";
- char *szResult;
- // add the two values
- jlong sum = value1+value2;
- // malloc room for the resulting string
- szResult = malloc(sizeof(szFormat) + 20);
- // standard sprintf
- sprintf(szResult, szFormat, sum);
- // get an object string
- jstring result = (*env)->NewStringUTF(env, szResult);
- // cleanup
- free(szResult);
- return result;
- }
- private native String getString(int value1, int value2);
- String result = getString(5,2);
- Log.v(DEBUG_TAG, "Result: "+result);
- result = getString(105, 1232);
- Log.v(DEBUG_TAG, "Result2: "+result);
然后,為了傳回結(jié)果,你可以使用一個叫作 NewStringUTF() 的 JNI helper 函數(shù)。該函數(shù)基本上就是獲取一個 C 語言字符串,以之創(chuàng)建一個新的 Java 對象。這個新的字符串對象就可以在之后作為結(jié)果返回,你就可以在 Java 類中將它作為一個常規(guī) Java 字符串對象使用了。

指令集、兼容性
Android NDK 需要 Android SDK 1.5 或更高版本。在新版本的 NDK 中,有些新的頭文件可用于擴(kuò)大對某些 API 的訪問——特別是 OpenGL ES 庫。
不過,那些都不是我們要談?wù)摰募嫒菪浴_@是原生代碼,在使用時由處理器構(gòu)架編譯。因此,你要問自己的一個問題會是它支持何種處理器構(gòu)架?在目前的 NDK 中(在本文撰寫時)它只支持 ARMv5TE 和 ARMv7-A 指令集。默認(rèn)設(shè)置下,目標(biāo)架構(gòu)被設(shè)置為 ARMv5TE,它可以在使用 ARM 芯片的 Android 設(shè)備上運(yùn)行。
它預(yù)計未來將支持其他指令集(其中提到了 x86)。這其中有很有意思的潛在狀況:NDK 解決方案無法適用于所有的設(shè)備。例如,市面上有使用 x86 指令集的英特爾(Intel)Atom 處理器的 Android 平板設(shè)備。
那么 NDK 在模擬器上如何呢?模擬器運(yùn)行的是真正的虛擬機(jī),包括完整的處理器虛擬。沒錯,這意味著在虛擬機(jī)中運(yùn)行 Java 就等于是在虛擬機(jī)中運(yùn)行了一個虛擬機(jī)。
總結(jié)
成果如何?你裝上了 Android NDK,最終完成了部分使用原生 C 語言代碼的功能完善、正常運(yùn)行的應(yīng)用程序了嗎?我們希望如此。在這一過程中有許多潛在的“出問題啦!”的可能,不過從某些方面來看,這些都是值得的。