【譯】NDK概述

翻譯自官方文檔NDK概述

NDK概述

On this page

  1. NDK使用前
  2. 介紹
  3. NDK怎樣工做
  4. Native Activitie和應用程序

開始前


本指南假設已經熟悉安卓開發中的本地程序的概念.html

介紹


本節提供了NDK如何工做的高級說明。Android NDK是一組高級工具,容許你的Android應用程序中嵌入C或C++(「native code&rdquo)。在Android應用中使用本地代碼的功能對於但願執行如下一項或多項操做的開發人員尤爲有用:java

  • 移植應用.
  • 重用現有庫, 或提供本身的庫以供重用.
  • 在某些狀況下提升性能, 尤爲像遊戲同樣的算密集的應用.

NDK如何工做


本節介紹在構建Android native應用程序時使用的主要組件, 並繼續描述構建和打包過程.android

主要組件

在構建應用程序時,您應該瞭解如下組件:api

  • ndk-build: NDK的核心是構建腳本,而後使用ndk-build運行該腳本。這些腳本包含的內容是:
    • 能自動探測到開發環境以及應用程序項目文件肯定要構建什麼.
    • 生成二進制文件.
    • 拷貝二進制文件到你的應用中.

    更多信息, 請查看ndk-build.數據結構

  • Java: Android構建進程將Java源代碼生成.dex(Dalvik可執行文件)文件,這個文件在運行Android操做系統的Dalvik虛擬機(「DVM」)中運行的。 即便應用程序根本不包含Java源代碼,構建進程仍然會生成一個.dex可執行文件,這個可執行文件包含了本地組件。當開發Java組件時,使用native關鍵字來講明它是一個本地方法。例以下面的方法聲明告訴編譯器它的實現是在一個庫中.

    When developing Java components, use the native keyword to indicate methods implemented as native code. For example, the following function declaration tells the compiler that the implementation is in a native library:oracle

    publicnativeint add(int  x,int  y);
  • 本地動態庫: NDK從本地源代碼構建這些庫或.so文件.

    注意: 若是兩個庫分別實現了相同的方法聲明,在C中會發生銜接錯誤, "簽名"意味着方法名惟一。在C++中, "簽名"意味着不只方法名稱,還意味着其參數名稱和類型.app

  • 本地靜態庫: NDK還能夠構建靜態庫或.a文件,你能夠將其連接到其餘庫.
  • Java本地接口(JNI): JNI是Java和C ++組件彼此通訊的接口.本指南假設知識JNI; 有關它的信息,請參閱 Java Navive接口規範.
  • 應用二進制接口(ABI): ABI準確地定義了應用程序的機器代碼在運行時與系統交互。NDK根據這些定義構建.so文件。 不一樣的ABI對應於不一樣的體系結構:NDK包括對ARMEABI(默認),MIPS和x86的ABI支持。 有關更多信息,請參閱ABI管理.

如下兩個項目只須要使用ndk-build 腳本進行構建,以及使用 ndk-gdb腳本進行調試。框架

  • Android.mk: 你必須在 jni目錄中建立一個 Android.mk配置文件。ndk-build腳本將會查看這個文件,他定義了模塊及名稱,要編譯的源文件,銜接標誌和庫。.
  • Application.mk: 此文件列舉和描述應用程序須要的模塊。此信息包括:
    • 編譯用給於特定平臺使用ABI.
    • 工具鏈.
    • 要包括的標準庫(靜態和動態STLport或默認系統).

流程

開發Android Native應用程序的通常流程以下:ide

  1. 設計應用程序, 決定Java中實現哪些部分, 以及本地代碼實現哪些部分.

    注意: 雖然能夠徹底避免Java,你會發現Android Java框架對於包括控制顯示和UI在內的任務很是有用.函數

  2. 像建立其它安卓項目同樣建立安卓項目.
  3. 若是你只開發一個純native應用程序,請在AndroidManifest.xml中聲明NativeActivity類。有關詳細信息,請參閱Native Activities和應用程序.
  4. 建立一個描述本地庫的Android.mk文件,這個文件包含了在"JNI"目錄下用於編譯的名稱,標識,銜接庫和源文件.
  5. 或者,你能夠建立一個Application.mk文件配置相應的ABI,工具鏈,發佈/調試模式和STL。若是你沒有任何配置,分別使用如下默認值:
    • ABI: armeabi
    • Toolchain: GCC 4.8
    • Mode: Release
    • STL: system
  6. 將原生代碼放在項目的 jni目錄下.
  7. 使用ndk-build編譯本地庫(.so, .a).
  8. 構建Java組件,生成可執行文件.dex文件.
  9. 將全部內容打包成APK文件,其中包含.so, .dex以及運行應用程序所需的其餘文件.

Native Activities和應用程序


Android SDK提供了一個幫助類NativeActivity, 它容許你寫一個徹底的NativeActivityNativeActivity處理Android框架和你的本地代碼之間的通訊,因此你沒必要讓它成爲派生類或調用它的方法。你只須要在AndroidManifest.xml文件中聲明你的應用程序是native應用程序。.

使用NativeActivity的Android應用程序仍然在其本身的虛擬機中運行,其它應用程序在沙盒中運行。你仍然能夠經過JNI訪問Android框架API,在某些狀況下,例如對於傳感器,輸入事件,資源文件,NDK提供本地接口調用,而沒必要經過JNI調用。有關此類支持的詳細信息,請參閱Android NDK Native APIs..

不管您是否正在開發native Activity, 咱們建議你使用傳統的Android構建工具建立項目。這樣作能確保構建和打包的應用程序是正確構造的.

Android NDK爲您提供兩種選擇來實現native activity:

  • native_activity.h頭文件定義了NativeActivity類的native版本,它包含建立Native Activity所需的回調接口和數據結構。由於你應用程序的主線程處理回調,你的回調實現不能阻塞,若是回調實現阻塞,你可能會收到ANR(應用程序不響應)錯誤,由於您的主線程沒有響應,直到回調返回。.
  • native_activity.h接口基礎上, android_native_app_glue.h文件定義了一個靜態輔助庫。它產生另外一個線程處理事件循環中的回調或輸入事件。將這些事件移動到單獨的線程防止任何回調阻塞你的主線程。.

<ndk_root>/sources/android/native_app_glue/android_native_app_glue.c 源文件是可用的, 容許你修改實現.

有關如何使用此靜態庫的更多信息,請查看native-activity示例應用程序和文檔。 進一步閱讀能夠查看在<ndk_root>/sources/android/native_app_glue/android_native_app_glue.h文件中的註釋.

使用native_activity.h接口

使用native_activity.h接口實現一個native activity

1.在你項目的根目錄下建立一個jni目錄。此目錄存儲全部本地代碼.

2.在在AndroidManifest.xml文件中聲明native activity文件中聲明native activity.

   由於你的應用程序沒有Java代碼,請將android:hasCode設置false.

<applicationandroid:label="@string/app_name"android:hasCode="false">

   你必須設置activity標記(android:name屬性)爲NativeActivity.

<activityandroid:name="android.app.NativeActivity"
            android:label="@string/app_name">

       注意: 你能夠建立一個NativeActivity的派生類,這是要把ndroid:name屬性值設爲派生類的類名.

  meta-data標籤的android:value屬性指定爲動態庫的名稱, 他包含了應用程序的入口點(例如C/C++的main函數),庫名省略lib前綴和.so後綴.

<meta-dataandroid:name="android.app.lib_name"
            android:value="native-activity"/>
            <intent-filter>
              <actionandroid:name="android.intent.action.MAIN"/>
              <categoryandroid:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
          </activity>
        </application>
      </manifest>

 

3.爲native activity建立一個文件,並實如今 ANativeActivity_onCreate變量中命名的函數。當native activity開始運行時應用程序將調用這個函數。這個函數相似於C/C++中的main函數,它接收一個指向ANativeActivity結構的指針,該結構體包含了各類須要你編寫實現的函數指針。在ANativeActivity->callbacks中的回調函數指針設置爲回調的實現.

4.將ANativeActivity->instance字段設置爲你想使用的任何特定數據實例的地址.

5.在Activity啓動前能夠實現你想作的其它一些工做.

6.在ANativeActivity->callbacks.中設置實現的其他回調,有關調用回調的更多信息,請查看 Activity生命週期..

7.開發應用程序的其他部分.

8.在項目的jni/目錄中建立一個Android.mk file文件,描述本地模塊信息以便構建系統編譯。有關詳細信息,請參閱Android.mk.

9.若是你有一個Android.mk文件, 使用ndk-build命令編譯本地代碼.

    $ cd <path>/<to>/<project>
    $ <ndk>/ndk-build

10.像以往同樣構建和安裝你的Android項目。若是您的本地代碼在jni/目錄中,構建腳本會自動將構建的.so文件打包到APK中.

相關文章
相關標籤/搜索