亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

按著步驟來,學習Android NDK入門很簡單

系統 1828 0

這是我轉的文章,是篇外文翻譯,將介紹如何學習安裝 Android NDK 并開始使用它。在這一教程結束后,將創建你自己的項目,從 Java 代碼簡單地調用原生C 語言代碼。

教程細節

技術: Android SDK、NDK、C 語言

難度: 進階

預計完成時間: 60-90 分鐘(⊙﹏⊙b汗,還是挺長時間的)

先決經驗:

在開始之前,需要先花點時間了解一下這一教程的難度。它的標記是“進階”。之所以標為“進階”是因為作者想要確保你符合以下要求:

1、有Java和C語言經驗。
2、能適應命令行操作。
3、知道如何了解你的 Cygwin、awk 和其他工具的版本。
4、能適應 Android Development。
5、有一個有效的 Android 開發環境(本文撰寫時,筆者使用的是 Android 2.2)
5、使用 Eclipse 或者可以將 Eclipse 的指導步驟輕松應用于自己的 IDE 上。
6、就算并不滿足這些條件,當然也歡迎你閱讀這一教程,不過可能在某些步驟遇到困難。

如果滿足了以上條件這些困難就會輕易解除。也就是說,即使認為自己是個移動開發老手,使用 NDK 依然很容易碰到困難和麻煩。請注意可能要自行排查故障才能讓一切正常運轉于你的開發系統中。

本教程提供完整的樣例項目的開源代碼。(我么有找到下載的東東)

何時使用 NDK 的說明

好,正在閱讀這篇教程的你,也許已經在考慮在你的 Android 項目中使用 NDK 了。不過,作者想要花點時間討論一下 NDK 為什么那么重要、何時該使用它,以及——同等重要的,何時不該使用它。

總的來說,只有當應用程序真的是個處理器殺手的時候,你才需要使用 NDK。也就是說,你設計的算法要利用 DalvikVM 中所有的處理器資源,而且原生運行較為有利。還有,別忘了在 Android 2.2 中,JIT 編譯器會提高類似代碼的效率。

另一個使用 NDK 的原因是方便移植。如果在現有的應用程序中有大量的 C 語言代碼,那么使用 NDK 不僅可以加速你項目的開發進程,也能在你的 Android 和非 Android 項目中保持修改的同步。這一點對于那些為其他平臺而寫的 OpenGL ES 應用程序來說尤為如此。

別以為只要用了原生代碼就能提高應用程序的效率。Java 與原生C 語言之間的轉換會增加一些資源開銷,因此只有你有一些集中消耗處理器資源的任務時才真正有必要這么做。

第 0 步:下載工具

好了,現在就開始吧!你需要下載 NDK。先來開始下載,因為在下載的過程中你可以檢查一下,確保所需要用到的其余工具的版本都正確。

從 Android 網站下載適合你的操作系統的 NDK。
現在,對照下列檢查你的工具版本:
1、如果在 Windows 下,Cygwin 1.7 或更高版本
2、將 awk 升級到最新版本(我們使用的是 20070501)
3、GNU Make 3.81 或更高版本(我們使用的是 3.81)

如果其中任何一個的版本太舊,請在繼續之前先升級。

第 1 步:安裝 NDK

既然 NDK 已經下載完成(沒錯吧?),你就需要解壓縮它。解壓后將它放入合適的目錄中。要把它放在和 Android SDK 相同的目錄下。 記住你把它放在哪里了

現在,你也許想要在路徑設置中添加 NDK 工具。如果你在 Mac 或 Linux 下,你可以用你的原生路徑設置來完成。如果你在 Windows 下的 Cygwin,你就需要設置 Cygwin 的路徑設置。

第 2 步:創建項目

創建一個常規的 Android 項目。為了避免日后的問題,你項目的路徑必須不包含空格。作者的項目有個叫做“com.mamlambo.sample.ndk1”的包,帶有一個叫做“AndroidNDK1SampleActivity”的默認 Activity——你之后還會看到它們。

在這個項目的頂層創建一個叫做“jni”的目錄——這是你放置原生代碼的地方。如果你很熟悉 JNI,那你就會知道 Android NDK 很大程度上基于 JNI 的概念——它本質上是個只有有限的 C 語言編譯頭文件的 JNI。

第 3 步:添加一些 C 語言代碼

現在,在 jni 文件夾中,創建一個叫做 native.c 的文件。一開始將以下 C 語言代碼寫入該文件,我們以后再添加另一個函數:

  1. #include
  2. #include
  3. #include
  4. #define DEBUG_TAG "NDK_AndroidNDK1SampleActivity"
  5. void Java_com_mamlambo_sample_ndk1_AndroidNDK1SampleActivity_helloLog(JNIEnv * env, jobject this, jstring logThis)
  6. {
  7. jboolean isCopy;
  8. const char * szLogThis = (*env)->GetStringUTFChars(env, logThis, &isCopy);
  9. __android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK:LC: [%s]", szLogThis);
  10. (*env)->ReleaseStringUTFChars(env, logThis, szLogThis);
  11. }
復制代碼
這個函數實際上非常淺顯。它獲取一個 Java 對象的字符串參數,將它轉換為 C-string,然后將它寫入到 LogCat 中。

不過該函數的名字很重要。它遵循了以“Java”的特定字樣開頭,后面跟著包名稱,然后類名稱,然后方法名稱,和 Java 中定義的一樣。每一部分都由一根下劃線隔開,而不是點。

該函數的頭兩個參數也很重要。第一個參數是 JNI 環境,它與 helper 函數會被頻繁調用。第二個參數是該函數所屬的Java 對象。

第 4 步:從 Java 中調用原生代碼

既然你已經寫好了原生代碼,讓我們回頭看看 Java 這邊。在默認的 Activity 中,按照你的喜好創建一個按鈕,并添加一個按鈕處理器。從按鈕處理器中,對 helloLog 作調用:
  1. helloLog("This will log to LogCat via the native call.");
復制代碼
然后你必須在 Java 這邊添加函數聲明。在你的 Activity 類中添加如下聲明:
  1. private native void helloLog(String logThis);
復制代碼
它告訴編譯和鏈接系統該方法將在原生代碼中實現。

最后,你需要加載原生代碼最終編譯到的庫。在 Activity 類中添加如下的靜態初始化程序來根據名稱加載庫(庫的名字隨你決定,在下一步還會用到):

  1. static {
  2. System.loadLibrary("ndk1");
  3. }
復制代碼
第 5 步:添加原生代碼的 Make 文件

在 jni 文件夾中,現在你需要添加在編譯中要用到的 makefile。該文件必須以“Android.mk”命名,如果你之前命名的文件為 native.c,庫為 ndk1,那么 Android.mk 的內容就應該是這樣:
  1. LOCAL_PATH := $(call my-dir)
  2. include $(CLEAR_VARS)
  3. LOCAL_LDLIBS := -llog
  4. LOCAL_MODULE := ndk1
  5. LOCAL_SRC_FILES := native.c
  6. include $(BUILD_SHARED_LIBRARY)
復制代碼
第 6 步:編譯原生代碼

既然你的原生代碼已完成,make 文件也已就緒,是時候編譯原生代碼了。在命令行下(Windows 用戶在 Cygwin 下),你需要在你的項目的根目錄下運行 ndk-build 命令。ndk-build 工具就在 NDK 工具目錄中。將它添加到我們的路徑中是最方便的辦法。
1.png
在之后的編譯中,如果你使用“ndk-build clean”命令,那么你可以確保所有的東西都被重新編譯了。

第 7 步:運行代碼

現在你已準備妥當可以運行代碼了。在你最喜歡的模擬器或者手持設備中載入該項目,查看 LogCat,然后點擊按鈕。
可能有兩件事情會發生。首先,它可能正常工作了。這樣的話,恭喜你!不過你可能還是想要繼續閱讀下去。

你也可能在 LogCat 中得到類似“Could not execute method of activity”這樣的錯誤。這很正常。這只是說明你漏掉了某個步驟罷了。用 Eclipse 很容易發生這種情況。通常,Eclipse 被設置為自動重編譯。

如果它不知道有東西被修改了,它就不會自動重編譯和重鏈接。在本例中,Eclipse 不知道你編譯了原生代碼。所以,“清除(cleaning)”該項目(在 Eclipse 工具欄中點擊項目(Project)->清除(Clean)),強制 Eclipse 重編譯。

第 8 步:添加另一個原生函數

接下來的函數將不僅演示返回值的能力,還會演示返回例如字符串這樣的對象的能力。在 native.c 中添加如下函數:
  1. jstring Java_com_mamlambo_sample_ndk1_AndroidNDK1SampleActivity_getString(JNIEnv * env, jobject this, jint value1, jint value2)
  2. {
  3. char *szFormat = "The sum of the two numbers is: %i";
  4. char *szResult;
  5. // add the two values
  6. jlong sum = value1+value2;
  7. // malloc room for the resulting string
  8. szResult = malloc(sizeof(szFormat) + 20);
  9. // standard sprintf
  10. sprintf(szResult, szFormat, sum);
  11. // get an object string
  12. jstring result = (*env)->NewStringUTF(env, szResult);
  13. // cleanup
  14. free(szResult);
  15. return result;
  16. }
復制代碼
為了正常編譯,你會需要添加一個 include stdio.h 的聲明。而且,為了響應這個新的原生函數,請在你的 Activity Java 類中添加如下聲明:
  1. private native String getString(int value1, int value2);
復制代碼
你現在可以隨意設定其功能。我們使用如下兩個調用和輸出:
  1. String result = getString(5,2);
  2. Log.v(DEBUG_TAG, "Result: "+result);
  3. result = getString(105, 1232);
  4. Log.v(DEBUG_TAG, "Result2: "+result);
復制代碼
回到 C 語言函數中,你會注意到我們做了許多事情。首先,我們在使用 malloc() 函數中的 sprintf() 調用時需要創建一個緩沖器(buffer)。如果你不會忘記通過使用 free() 函數清理結果,那么這就很合理了。

然后,為了傳回結果,你可以使用一個叫作 NewStringUTF() 的 JNI helper 函數。該函數基本上就是獲取一個 C 語言字符串,以之創建一個新的 Java 對象。這個新的字符串對象就可以在之后作為結果返回,你就可以在 Java 類中將它作為一個常規 Java 字符串對象使用了。
2.png

指令集、兼容性
Android NDK 需要 Android SDK 1.5 或更高版本。在新版本的 NDK 中,有些新的頭文件可用于擴大對某些 API 的訪問——特別是 OpenGL ES 庫。

不過,那些都不是我們要談論的兼容性。這是原生代碼,在使用時由處理器構架編譯。因此,你要問自己的一個問題會是它支持何種處理器構架?在目前的 NDK 中(在本文撰寫時)它只支持 ARMv5TE 和 ARMv7-A 指令集。默認設置下,目標架構被設置為 ARMv5TE,它可以在使用 ARM 芯片的 Android 設備上運行。

它預計未來將支持其他指令集(其中提到了 x86)。這其中有很有意思的潛在狀況:NDK 解決方案無法適用于所有的設備。例如,市面上有使用 x86 指令集的英特爾(Intel)Atom 處理器的 Android 平板設備。

那么 NDK 在模擬器上如何呢?模擬器運行的是真正的虛擬機,包括完整的處理器虛擬。沒錯,這意味著在虛擬機中運行 Java 就等于是在虛擬機中運行了一個虛擬機。

總結
成果如何?你裝上了 Android NDK,最終完成了部分使用原生 C 語言代碼的功能完善、正常運行的應用程序了嗎?我們希望如此。在這一過程中有許多潛在的“出問題啦!”的可能,不過從某些方面來看,這些都是值得的。

按著步驟來,學習Android NDK入門很簡單


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 亚洲另类第一页 | 亚洲精品久久婷婷爱久久婷婷 | 国产乱子伦一区二区三区 | 99精品国产在这里白浆 | 一区二区三区视频 | 午夜精品久久久久久久99 | 久久y| 婷婷尹人香蕉久久天堂 | 久久国产加勒比精品无码 | 四虎影视成人精品 | 日韩综合色 | 免费一极毛片 | 亚洲国产精久久久久久久春色 | 久久精品一区二区免费看 | 热久久久久久 | 国产一级特黄aa毛片 | 色婷婷激婷婷深爱五月小蛇 | 精品无人乱码区1区2区3区 | 国产真实偷乱视频在线观看 | 在线欧美一区 | 深夜在线网址 | 九九视频精品在线 | 欧美成人亚洲高清在线观看 | 成年人精品视频 | 欧美日韩一本大道香蕉欧美 | 国产激情视频趣趣在线观看的 | 91精品国产一区二区三区左线 | 伊人五月天婷婷琪琪综合 | 免费在线观看黄色小视频 | 婷婷国产 | 免费福利在线播放 | 久久久久久免费观看 | 羞羞色院91蜜桃在线观看 | 一区二区三区在线观看视频 | 国产视频自拍一区 | 俺去也理论网站 | www.亚洲视频 | 99久久精品在免费线18 | 欧美中文字幕在线观看 | 老司机午夜网站 | 欧美成人怡红院在线观看 |