Android NDKhtml
NDK
是一組容許你將 C 或 C++嵌入到 Android 應用中的工具。經過NDK開發咱們能夠在平臺之間移植應用(音視頻開源庫FFmpeg、開源視覺庫OpenCV等等),在一些計算密集型的APP(好比遊戲開發)中咱們也須要作一些算法的移植工做。能夠看出來NDK就是原生開發工具包,在AndroidStudio中咱們在經過SDK Manager進行NDK工具包的更新和安裝。NDK是屬於Android的和Java沒有特定的關係。android
Android JNI算法
Java Native Interface
Java本地接口,JNI是屬於Java特有的特性,主要做用是讓Java和C++、C等其餘本地語言進行交互。經過JNI,可讓Java具有跨平臺的特性,加強Java和本地語言交互的能力。函數
NDK是Android SDK自帶的工具開發包,用於快速的開發C和C++的動態代碼庫,並將相關的so文件打包進APK文件中。JNI是Java語言加強的特性之一,用於Java與本地語言的交互。總結下來:JNI是實現的終極目標,而NDK是Android集成開發環境實現JNI目標的手段。經過NDK實現JNI目標。工具
須要注意: NDK提供的庫自己也是有限的,僅僅用於處理算法效率和敏感的問題,NDK提供了交叉編譯器,用於生成特定的CPU的平臺動態庫,另外NDK還提供了.so文件和.apk打包的工具。開發工具
還記的AndroidStudio2.2的版本嗎?還記得Eclipse開發NDK嗎?簡直苦不堪言啊。考慮到目前大部分同窗已經遷移到AndroidStudio,何況我相信絕大同窗的版本已經在3.2了吧。咱們直接就講解最新的AndroidStudio集成NDK開發的方式。gradle
一個支持了NDK的Android的項目有哪些須要注意的點呢?ui
若是要手動將 Gradle 與你的本地庫相關聯,你須要在 module 層級的 build.gradle 文件中添加 externalNativeBuild {}
代碼塊,而且在該代碼塊中配置 cmake {}
或 ndkBuild {}
。能夠看到AndroidStudio默認使用Cmake構建系統。後續咱們着重來講。spa
cmake {
cppFlags "-frtti -fexceptions" //這裏的設置了一些可選的標識符給C++的編譯器,這也是咱們以前在建立項目時候勾選的
}
複製代碼
add_library()
、find_library
和target_link_libraries
都是Cmake腳本中定義的命令函數。其餘一些Cmake腳本語法能夠參見https://cmake.org/cmake/help/v3.0/command/find_library.html(注意版本區分)。插件
add_library
使用指定的源文件向工程中添加一個庫。函數原型以下:
add_library(<name> [STATIC | SHARED | MODULE]
[EXCLUDE_FROM_ALL]
source1 source2 ... sourceN)
# STATIC:靜態庫,是目標文件的歸檔文件,在連接其它目標的時候使用
# SHARED:動態庫,會被動態連接,在運行時被加載
# MODULE:模塊庫,是不會被連接到其它目標中的插件,可是可能會在運行時使用dlopen-系列的函數
複製代碼
find_library
用於查找一個庫文件。函數原型以下:
find_library(
<VAR>
name | NAMES name1 [name2 ...]
[HINTS path1 [path2 ... ENV var]]
[PATHS path1 [path2 ... ENV var]]
[PATH_SUFFIXES suffix1 [suffix2 ...]]
[DOC "cache documentation string"]
[NO_DEFAULT_PATH]
[NO_CMAKE_ENVIRONMENT_PATH]
[NO_CMAKE_PATH]
[NO_SYSTEM_ENVIRONMENT_PATH]
[NO_CMAKE_SYSTEM_PATH]
[CMAKE_FIND_ROOT_PATH_BOTH |
ONLY_CMAKE_FIND_ROOT_PATH |
NO_CMAKE_FIND_ROOT_PATH]
)
# android系統每一個類型的庫會存放一個特定的位置,而log庫存放在log-lib中
複製代碼
target_link_libraries
設置要連接的庫文件的名稱。函數原型以下:
target_link_libraries(<target> [item1 [item2 [...]]]
[[debug|optimized|general] <item>] ...)
複製代碼
經過上面的解析,咱們知道AndroidStudio默認使用Cmake進行NDK構建環境,經過在CMakeLists.txt中進行編輯命令的編寫,使得C++/C的代碼能夠經過Cmake工具進行編譯。
Java:函數的native申明是在MainActivity中。咱們再看看MainActivity文件,與之前的jni調用方式完成同樣,包括了庫的加載、native方法申明、jni方法調用三個過程。在native方法中經過點擊鼠標左鍵能夠直接跳轉到C++的源碼裏。
C++:這裏是咱們須要經過C/C++進行代碼編寫的地方。
咱們在AndroidStudio中進行運行,把項目跑到手機中,當咱們點擊TextView,咱們能夠看到Hello from C++,說明咱們成功進行了Java和C++代碼的相互調用,也完成了JNI第一個入門程序的分析。
上面咱們看到了如何在項目剛剛建立的時候集成NDK開發,若是針對一個已經開發的項目,那麼如何進行NDK的集成呢?
配置項目支持JNI開發,在項目模塊右鍵選擇Link C++ Project with Gradle。
在彈出的提示框中選擇剛新建配置的CMakeLists.txt文件,並點擊OK。
經過上述的步驟,咱們能夠看到AndroidStudio會幫咱們在gradel腳本文件中自動建立externalNativeBuild {}
代碼塊,而且在該代碼塊中配置 cmake {}
代碼塊了。接下來咱們就能夠在Java代碼中進行庫的加載、native方法申明、jni方法調用三部曲了。
如今,你是否是對NDK有了初步的瞭解了呢?後續將會進一步分享NDK,請你們保持關注。