參考:https://developer.android.com/studio/projects/add-native-code.html#link-gradlehtml
使用Android Studio 2.2以上版本、Android插件 Gradle 2.2.0以上版本,能夠將C/C++代碼編譯成native庫,而後Gradle將庫打包到APK中。Java代碼能夠經過JNI(Java Native Interface)調用native庫中的函數。android
本文所用環境爲爲Android Studio 2.2.2。函數
用Android Studio集成的SDK Manager安裝NDK、CMake和LLDB。其中CMake是編譯工具,LLDB是調試工具。工具
勾選Include C++ Supportgradle
到下面這一步時,有三個選項:ui
C++ Standard:選擇要用的C++標準,個人列表裏有Toolchain Default和C++ 11,因爲對C++標準沒要求,我直接選Default,也就是編譯工具(默認爲CMake)的默認配置。插件
Exceptions Support:若是勾選,則編譯時支持C++異常處理。Android Studio會在module對應的build.gradle中的cppFlags中添加 -fexceptions,這個cppFlags會被Gradle傳遞給CMake。debug
Runtime Type Information Support:若是勾選,則支持RTTI,Android Studio會在module對應的build.gradle中的cppFlags中添加 –frtti。3d
注:RTTI,(Run-Time Type Identification),經過RTTI, 程序可以使用基類的指針或引用來檢查這些指針或引用所指的對象的實際派生類型。指針
所有勾選,點擊Finish完成工程的建立。
工程新建完成後,能夠看到如上的目錄,其中:
cpp中包含了全部項目中使用的native源碼文件、頭文件和預編譯庫。native-lib.cpp是Android Studio自動生成的一個sample文件,放在module的src/main/cpp中。
External Build Files中包含了CMake或ndk-build的編譯腳本。CMakeLists.txt是Android Studio自動生成的一個CMake腳本,放在module的根目錄中。
點擊Run,編輯並運行這個工程,APP呈現以下的界面:
下面就是編譯和運行這個APP時發生的事情:
1.Gradle調用外部的編譯腳本CMakeLists.txt
2.CMake執行編譯腳本中的命令,將C++源文件(native-lib.cpp)編譯成共享對象庫(libnative-lib.so),Gradle再將這個so庫打包到APK中。
生成的libnative-lib.so在module對應的build\intermediates\cmake\debug\obj中,以下圖所示:
用APK Analyser能夠看到APK中打包了libnative-lib.so庫:
Build->Analyze APK..,以下:
3.運行時,MainActivity經過System.LoadLibrary()加載native庫,而後庫中的native方法就能夠用了。下面是MainActivity中的代碼。
1.在module的cpp文件夾中,右鍵,new->C++ Class或者C/C++ Source File。
新建完成後,不會立刻在Android目錄結構中看到文件,打開新建的文件,會提示需在編譯文件中添加該文件,而且同步工程。
2.在CMakeLists.txt中,添加對新建cpp文件的配置。
3.點擊Sync Now,同步完成後,就能夠在Android目錄結構下看到新建的文件了。
1.CMake的編譯腳本必須命名爲CMakeLists.txt
若是不是,就會報錯,以下:
2.CMakeLists.txt最好放在module的根目錄
其實放在任意目錄均可以,可是文件中聲明的C/C++文件路徑,都是相對於編譯腳本文件所在的目錄。
3.CMake默認將庫文件命名爲:
可是在使用時,仍然使用library-name導入就好了。
4.CMake 命令:
(1)cmake_minimum_required(VERSION 3.4.1) - 指定CMake最低版本
(2)add_library(...) - 聲明庫名稱、類型、源碼文件
(3)include_directories() - 指定關聯的頭文件目錄
(4)find_library() - 定位某個NDK庫,並將其路徑存儲爲一個變量,能夠在其餘地方用這個變量引用NDK庫
(5)target_link_libraries() - 將NDK庫連接到native庫中,這樣native庫才能調用NDK庫中的函數
5.將NDK目錄下的源碼編譯到native庫中:
其中,ANDROID_NDK是AndroidStudio自動定義好的變量。
6.添加其餘預編譯庫
須要用IMPORT標誌,告訴CMake,只須要引用這個預編譯庫(不須要進行編譯)。
而後用set_target_properties()指定庫的路徑。
其中ANDROID_ABI這個變量列出了NDK支持的全部ABI(Application Binary Interface),用這個變量可讓CMake引用多個ABI對應的庫文件。
固然,還要指定頭文件路徑:
最後,用target_link_libraries()將預編譯庫連接到native庫中。