1、創(chuàng)建新項(xiàng)目(Create New Project)
點(diǎn)擊File — New — New Project,把Include C++ Support前面的CheckBook勾上,然后依次進(jìn)行接下來的操作

create new project
2、配置C++支持功能(Customize C++ Support)
在Customize C++ Support界面默認(rèn)即可

customize C++ Support
- C++ Standard
指定編譯庫的環(huán)境,其中Toolchain Default使用的是默認(rèn)的CMake環(huán)境;C++ 11也就是C++環(huán)境。- Exceptions Support
如果選中復(fù)選框,則表示當(dāng)前項(xiàng)目支持C++異常處理,如果支持,在項(xiàng)目Module級別的build.gradle文件中會增加一個標(biāo)識 -fexceptions到cppFlags屬性中,并且在so庫構(gòu)建時,gradle會把該屬性值傳遞給CMake進(jìn)行構(gòu)建。- Runtime Type Information Support
同理,選中復(fù)選框,項(xiàng)目支持RTTI,屬性cppFlags增加標(biāo)識-frtti

JniCmake項(xiàng)目主體結(jié)構(gòu)
3、CMakeLists.txt構(gòu)建
CMakeLists.txt文件用于配置JNI項(xiàng)目屬性,主要用于聲明CMake使用版本、so庫名稱、C/CPP文件路徑等信息,下面是該文件內(nèi)容:
# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html
# 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
# Provides a relative path to your source file(s).
src/main/cpp/native-lib.cpp )
# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log )
# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.
target_link_libraries( # Specifies the target library.
native-lib
# Links the target library to the log library
# included in the NDK.
${log-lib} )
cmake_minimum_required(VERSION 3.4.1)
CMake最小版本使用的是3.4.1。add_library()
配置so庫信息(為當(dāng)前腳本文件添加庫)
- native-lib這個是聲明引用so庫的名稱,在項(xiàng)目中,如果需要使用這個so文件,引用的名稱就是這個。值得注意的是,實(shí)際上生成的so文件名稱是libnative-lib。當(dāng)Run項(xiàng)目或者build項(xiàng)目是,在Module級別的build文件下的intermediates\transforms\mergeJniLibs\debug\folders\2000\1f\main
下會生成相應(yīng)的so庫文件。- SHARED這個參數(shù)表示共享so庫文件,也就是在Run項(xiàng)目或者build項(xiàng)目時會在目錄intermediates\transforms\mergeJniLibs\debug\folders\2000\1f\main
下生成so庫文。此外,so庫文件都會在打包到.apk里面,可以通過選擇菜單欄的Build->Analyze Apk...*查看apk中是否存在so庫文件,一般它會存放在lib目錄下。- src/main/cpp/native-lib.cpp 構(gòu)建so庫的源文件。
- STATIC:靜態(tài)庫,是目標(biāo)文件的歸檔文件,在鏈接其它目標(biāo)的時候使用。
- SHARED:動態(tài)庫,會被動態(tài)鏈接,在運(yùn)行時被加載。
- MODULE:模塊庫,是不會被鏈接到其它目標(biāo)中的插件,但是可能會在運(yùn)行時使用dlopen-系列的函數(shù)動態(tài)鏈接
include_directories
配置頭文件路徑目錄find_library()
這個方法與我們要創(chuàng)建的so庫無關(guān)而是使用NDK的Apis或者庫,默認(rèn)情況下Android平臺集成了很多NDK庫文件,所以這些文件是沒有必要打包到apk里面去的。直接聲明想要使用的庫名稱即可(猜測:貌似是在Sytem/libs目錄下)。在這里不需要指定庫的路徑,因?yàn)檫@個路徑已經(jīng)是CMake路徑搜索的一部分。如示例中使用的是log相關(guān)的so庫。
- log-lib這個指定的是在NDK庫中每個類型的庫會存放一個特定的位置,而log庫存放在log-lib中
- log指定使用log庫
-
target_link_libraries()
如果你本地的庫(native-lib)想要調(diào)用log庫的方法,那么就需要配置這個屬性,意思是把NDK庫關(guān)聯(lián)到本地庫。
- native-lib要被關(guān)聯(lián)的庫名稱
- ${log-lib}要關(guān)聯(lián)的庫名稱,要用大括號包裹,前面還要有$符號去引用。
實(shí)際上,我們可以自己創(chuàng)建CMakeLists.txt文件,而且路徑不受限制,只要在build.gradle中配置externalNativeBuild.cmake.path來指定該文件路徑即可
4、MainActivity調(diào)用和運(yùn)行結(jié)果

MainActivity

JniCmake運(yùn)行效果圖
其它
- 我的CSDN博客地址:http://blog.csdn.net/s003603u
- 我的GitHub地址:https://github.com/soulrelay
- 我的簡書地址:http://m.itdecent.cn/u/514ca03bbc17
- 我的掘金地址:https://juejin.im/user/56f3d9d1816dfa00522b8f20
- 我的個人站點(diǎn): http://sushuai.tech/