NDK系列(一)-AS使用javah生成so文件
NDK系列(二)-AS使用CmakeLists生成so文件
NDK系列(三)-AS編寫C文件沒有提示和不識(shí)別NULL
NDK系列(四)-AS生成jar包、導(dǎo)入so庫(kù)并使用方法
接著搗鼓ndk,我們?cè)陂_發(fā)的時(shí)候,不可避免的需要使用一些三方庫(kù),提高自己的開發(fā)效率,同時(shí)也可以避免自己在某一方面的缺點(diǎn)和短板,這是我們?cè)谧霭沧吭_發(fā)的套路,那么ndk開發(fā)呢,也是同樣如此,需要導(dǎo)入一些so文件的三方庫(kù),來方便我們的開發(fā)。以NDK系列一、二的兩個(gè)demo為例子,比如我們需要那個(gè)so文件的方法,在系列一的demo jnilibarary的C文件中添加一個(gè)add方法,我們想要在系列二的C文件中調(diào)用這個(gè)方法(假設(shè)這個(gè)方法邏輯很復(fù)雜,重寫需要很浪費(fèi)時(shí)間或者你不會(huì)這方面的知識(shí),需要三方庫(kù)來補(bǔ)充),那么就需要把系列一生成的C文件導(dǎo)入系列二的項(xiàng)目中(后面我會(huì)把項(xiàng)目放在git上,需要的自己去down)
第一步:生成一個(gè)三方so庫(kù)

在main.c的文件中添加一個(gè)add方法,傳入兩個(gè)參數(shù),返回他們的和。其他的不需要修改什么,直接生成so文件就Ok了,至于怎么生成so文件,請(qǐng)參考系列一的介紹。

這里需要額外注意的是,要記住生成的so庫(kù)的名字,也就是gradle ndk 設(shè)置的那個(gè)名字。

第二步:導(dǎo)入三方so庫(kù)
上個(gè)文章我導(dǎo)入so庫(kù)放在默認(rèn)目錄jniLibs下的,這次我放在libs文件下,做個(gè)對(duì)比。
在gradle中加入
sourceSets.main{
jniLibs.srcDirs = ['libs']
jni.srcDirs = []
}
把三方的so庫(kù)放在libs的目錄下。接下來編寫CmakeList.txt文件,這個(gè)比較麻煩了。
我先把我的文件展示出來,在解釋。
# Sets the minimum version of CMake required to build the native
# library. You should either keep the default value or only pass a
# value of 3.4.0 or lower.
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 it for you.
# Gradle automatically packages shared libraries with your APK.
#設(shè)置生成的so動(dòng)態(tài)庫(kù)最后輸出的路徑
#set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/../jniLibs/${ANDROID_ABI})
find_library(
log-lib
log )
#設(shè)置so庫(kù)
set(my_lib_path ${CMAKE_SOURCE_DIR}/libs)
add_library( nativeUtil
SHARED
IMPORTED )
set_target_properties( nativeUtil
PROPERTIES IMPORTED_LOCATION
${my_lib_path}/${ANDROID_ABI}/libnativeUtil.so )
add_library(
native-lib
SHARED
src/main/cpp/native-lib.c )
target_link_libraries(
native-lib
nativeUtil
${log-lib} )
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
1、set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/../jniLibs/${ANDROID_ABI}) 這句被我注釋了,是用來設(shè)置生成so文件的路徑。我設(shè)置生成的so文件放在了jniLibs下。如果不設(shè)置,是有一個(gè)默認(rèn)的路徑的。文件夾名是cmake開頭。

默認(rèn)位置在圖示這個(gè)位置。
2、find_library( log-lib log ) 這個(gè)是Camakelist項(xiàng)目生成時(shí)默認(rèn)導(dǎo)入的打印三方庫(kù)。
3、set(my_lib_path ${CMAKE_SOURCE_DIR}/libs) 這個(gè)是為了下面使用方便,設(shè)置了一個(gè)參數(shù),my_lib_path代表的是我當(dāng)前Cmakelist所在根目錄下的libs這個(gè)文件夾。
4、add_library( nativeUtil SHARED IMPORTED ) 添加名為nativeUtil的三方庫(kù),這個(gè)名字就是我們生成so文件時(shí)設(shè)置的名字。
5、set_target_properties( nativeUtil PROPERTIES IMPORTED_LOCATION ${my_lib_path}/${ANDROID_ABI}/libnativeUtil.so ) 設(shè)置nativeUtil庫(kù)的連接位置,在CmakeList根目錄的libs文件夾下的所有android abi平臺(tái)的名叫l(wèi)ibnativeUtil.so的文件。全部連接入項(xiàng)目。
6、add_library( native-lib SHARED src/main/cpp/native-lib.c ) 這個(gè)是創(chuàng)建項(xiàng)目時(shí)自動(dòng)生成的,該項(xiàng)目的so庫(kù)取名為native-lib,當(dāng)然也可以換成其他的名字,注意不要與導(dǎo)入三方庫(kù)重名。后面的是該項(xiàng)目對(duì)應(yīng)的c文件位置。
7、target_link_libraries( native-lib nativeUtil ${log-lib} ) 開始鏈接庫(kù),這里有個(gè)著重注意的點(diǎn),就是放在第一個(gè)的庫(kù)名稱必須是當(dāng)前的庫(kù)名稱,也就是native-lib,不能將nativeUtil放在前面。
第三步:使用so庫(kù)C方法
手動(dòng)創(chuàng)建一個(gè)h文件,extern 做前綴,extern意思是從別的庫(kù)導(dǎo)入的方法。
extern int add(int a,int b);

接下來就是,編寫當(dāng)前項(xiàng)目的C文件。

將頭文件直接導(dǎo)入C文件,然后在MainActivity創(chuàng)建一個(gè)jni方法,在MainActivity導(dǎo)入兩個(gè)庫(kù),調(diào)用方法就ok了。

點(diǎn)擊運(yùn)行,就ok了。

好啦,這就是使用別人的so文件,編寫自己的so文件。踩坑踩著踩著就成長(zhǎng)了,哈哈~~
系列一javah創(chuàng)建的demo git:https://github.com/SingleShu/JniJavahTest
系列二cmakelist創(chuàng)建的git : https://github.com/SingleShu/JniCmakeTest
感謝動(dòng)腦學(xué)院NDK專題資源
|