最近使用AndroidStudio的最新ndk編譯方式cMake來編譯底層cpp文件,因爲以前沒有接觸過cMake語法,先附上官方學習文檔地址:https://developer.android.com/ndk/guides/cmake.html,以及友情中文翻譯網址:https://www.zybuluo.com/khan-lau/note/254724;html
底層c文件一大堆,以下圖所示java
問題一:android
其中native-lib.cpp是提供對外接口的,因此對其餘文件的依賴都寫在了該文件中,接下來直接編譯嗎?no,那樣你會獲得編譯錯誤,在native-lib.cpp中找不到其餘c文件裏邊的函數。因此是cMake編譯的時候沒有把那些c文件編譯進去,這樣要去CMakeLists.txt中去添加文件了。c++
未修改以前的CMakeLists.txt文件內容是這樣的:ide
# Sets the minimum version of CMake required to build the native library. cmake_minimum_required(VERSION 3.4.1) # Creates and names a library, sets it as either STATIC # or SHARED, and provides the relative paths to its source code. # You can define multiple libraries, and CMake builds them for you. # Gradle automatically packages shared libraries with your APK. add_library( # Sets the name of the library. native-lib # Sets the library as a shared library. SHARED EXCLUDE_FROM_ALL # Provides a relative path to your source file(s). src/main/cpp/native-lib.cpp )
學習CMake的官方文檔能夠知道,其中的add_library()正是設置生成包的地方,這裏只有native-lib.cpp一個文件,理論上應該要包括其餘那些的,那麼加上其餘那幾個文件就行了吧?是能夠這樣,可是那麼多文件,未免也太長了吧,固然CMake確定預料到這種問題了,因此咱們能夠get一個新技能,使用aux_source_directory(),在源文件位置添加文件列表,而不是單個文件,get修改以後的文件內容以下:函數
# Sets the minimum version of CMake required to build the native library. cmake_minimum_required(VERSION 3.4.1) # Creates and names a library, sets it as either STATIC # or SHARED, and provides the relative paths to its source code. # You can define multiple libraries, and CMake builds them for you. # Gradle automatically packages shared libraries with your APK. aux_source_directory(src/main/cpp SRC_LIST) add_library( # Sets the name of the library. native-lib # Sets the library as a shared library. SHARED EXCLUDE_FROM_ALL # Provides a relative path to your source file(s). #src/main/cpp/native-lib.cpp ${SRC_LIST} )
這樣子改完須要Synchronize同步一下,這樣就能夠從新編譯了。學習
問題二:ui
在編譯經過以後,運行調用底層代碼,結果程序崩潰了,提示java.lang.UnsatisfiedLinkError: Native method not found: ***;好吧,沒有找到這個底層方法?但是明明已經生成了,仔細觀察上圖代碼結構能夠發現,因爲AndroidStudio自動生成的底層文件是.cpp的,也就是使用了c++的語法規則,而其餘的底層文件都是.c的使用的c語言規則,他們二者之間仍是有區別的,如今須要在cpp文件中調用c文件,那麼要在cpp文件中作些修改,首先頭文件包含c的是相同的,不一樣點是在使用c文件中的函數上方,加一行 extern "C" 便可。這樣從新編譯運行,一切正常!spa