Android NDK入門基礎筆記

原生開發套件 (NDK) 是一套工具,使您能夠在 Android 應用中使用 C 和 C++ 代碼。

使用 NDK 將 C 和 C++ 代碼編譯到原生庫中,然後使用 Android Studio 的集成構建系統 Gradle 將原生庫打包到 APK 中。Java 代碼隨後可以通過Java原生接口(JNI)調用原生庫中的函數。

NDK的作用:

  • 進一步提升設備性能,以降低延遲,或運行計算密集型應用,如遊戲或物理模擬。
  • 重複使用您自己或其他開發者的 C 或 C++ 庫。

Android Studio 編譯原生庫的默認構建工具是CMake。

 

1.下載NDK和工具:

應用編譯和調試原生代碼,您需要以下組件:

  • Android 原生開發套件 (NDK):這套工具使您能在 Android 應用中使用 C 和 C++ 代碼。
  • CMake:一款外部編譯工具,可與 Gradle 搭配使用來編譯原生庫。如果您只計劃使用 ndk-build,則不需要此組件。
  • LLDB:Android Studio 用於調試原生代碼的調試程序。

安裝配置NDK和CMake

 

2.創建CMake構建腳本:

CMake 構建腳本是一個純文本文件,必須將其命名爲 CMakeLists.txt,並在其中包含 CMake 構建您的 C/C++ 庫時需要使用的命令。

CMake命令集

 # Sets the minimum version of CMake required to build your native library.
    # This ensures that a certain set of CMake features is available to
    # your build.

    cmake_minimum_required(VERSION 3.4.1)

    # Specifies a library name, specifies whether the library is STATIC or
    # SHARED, and provides relative paths to the source code. You can
    # define multiple libraries by adding multiple add_library() commands,
    # and CMake builds them for you. When you build your app, Gradle
    # automatically packages shared libraries with your APK.

    add_library( # Specifies the name of the library.
                 native-lib

                 # Sets the library as a shared library.
                 SHARED

                 # Provides a relative path to your source file(s).
                 src/main/cpp/native-lib.cpp )

    # Specifies a path to native header files.
        include_directories(src/main/cpp/include/)

    find_library( # Defines the name of the path variable that stores the
                  # location of the NDK library.
                  log-lib

                  # Specifies the name of the NDK library that
                  # CMake needs to locate.
                  log )

     # Links your native library against one or more other native libraries.
    target_link_libraries( # Specifies the target library.
                           native-lib

                           # Links the log library to the target library.
                           ${log-lib} )

CMake命令解釋:

  • cmake_minimum_required():設置CMake所需要的最小版本;
  • add_library():設置共享庫的名字,設置共享類型,添加C/C++原生代碼;名字規範爲liblibrary-name.so,library-name爲庫名字,如libnative-lib.so共享庫爲native-lib,在Android中加載如下:
static {
        System.loadLibrary("native-lib");
    }

          共享類型有:STATIC/SHARED/MUDULE,STATIC:是對象文件的存檔,用於鏈接其他目標;SHARED:靜態加載和運行時加載;MUDULE:是沒有鏈接到其他目標的插件,但是可以在運行時使用dlopen-link功能動態加載;

          添加C/C++原生代碼:添加C/C++的相對路徑。

  • find_library():以找到 NDK 庫並將其路徑存儲爲一個變量。可以使用此變量在構建腳本的其他部分引用 NDK 庫;
  • target_link_libraries():爲了讓原生庫能夠調用如 log 庫中的函數;

關聯到原生庫:

  • NDK 還以源代碼的形式包含一些庫,您將需要構建這些代碼並將其關聯到您的原生庫。您可以使用 CMake 構建腳本中的 add_library() 命令將源代碼編譯到原生庫中。要提供本地 NDK 庫的路徑,您可以使用 Android Studio 自動爲您定義的 ANDROID_NDK 路徑變量,以下命令告訴 CMake 要編譯 android_native_app_glue.c(負責管理 NativeActivity生命週期事件和觸摸輸入),並將其鏈接到靜態庫 native-lib 中:
add_library( app-glue
                 STATIC
                 ${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c )

    # You need to link static libraries against your shared native library.
    target_link_libraries( native-lib app-glue ${log-lib} )

添加其他預構建庫:

include_directories( imported-lib/include/ )
    
add_library( imported-lib
                 SHARED
                 IMPORTED )

set_target_properties( # Specifies the target library.
                         imported-lib

                       # Specifies the parameter you want to define.
                         PROPERTIES IMPORTED_LOCATION

                       # Provides the path to the library you want to import.
                         imported-lib/src/${ANDROID_ABI}/libimported-lib.so )
  • set_target_properties():命令指定庫的路徑,${ANDROID_ABI}添加庫的多個 ABI 版本的相對路徑。
  • IMPORT:標記CMake將預構建庫導入項目中;
  • include_directories():定位構建庫的頭文件;

包含其他CMake項目:

    # Sets lib_src_DIR to the path of the target CMake project.
    set( lib_src_DIR ../gmath )

    # Sets lib_build_DIR to the path of the desired output directory.
    set( lib_build_DIR ../gmath/outputs )
    file(MAKE_DIRECTORY ${lib_build_DIR})

    # Adds the CMakeLists.txt file located in the specified directory
    # as a build dependency.
    add_subdirectory( # Specifies the directory of the CMakeLists.txt file.
                      ${lib_src_DIR}

                      # Specifies the directory for the build outputs.
                      ${lib_build_DIR} )

    # Adds the output of the additional CMake build as a prebuilt static
    # library and names it lib_gmath.
    add_library( lib_gmath STATIC IMPORTED )
    set_target_properties( lib_gmath PROPERTIES IMPORTED_LOCATION
                           ${lib_build_DIR}/${ANDROID_ABI}/lib_gmath.a )
    include_directories( ${lib_src_DIR}/include )

    # Links the top-level CMake build output against lib_gmath.
    target_link_libraries( native-lib ... lib_gmath )

要構建多個 CMake 項目並在 Android 項目中包含它們的輸出,可以使用一個CMakeLists.txt個作爲頂級CMake構建腳本,加其他 CMake 項目作爲此構建腳本的依賴項;

  • add_subdirectory():將另一個 CMakeLists.txt 文件指定爲構建依賴項,然後關聯其輸出。

 

3.Java原生接口(JNI):

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章