【移動(dòng)應(yīng)用開發(fā)技術(shù)】Android Studio中通過CMake使用NDK并編譯自定義庫(kù)和添加預(yù)編譯庫(kù)_第1頁(yè)
【移動(dòng)應(yīng)用開發(fā)技術(shù)】Android Studio中通過CMake使用NDK并編譯自定義庫(kù)和添加預(yù)編譯庫(kù)_第2頁(yè)
【移動(dòng)應(yīng)用開發(fā)技術(shù)】Android Studio中通過CMake使用NDK并編譯自定義庫(kù)和添加預(yù)編譯庫(kù)_第3頁(yè)
【移動(dòng)應(yīng)用開發(fā)技術(shù)】Android Studio中通過CMake使用NDK并編譯自定義庫(kù)和添加預(yù)編譯庫(kù)_第4頁(yè)
【移動(dòng)應(yīng)用開發(fā)技術(shù)】Android Studio中通過CMake使用NDK并編譯自定義庫(kù)和添加預(yù)編譯庫(kù)_第5頁(yè)
已閱讀5頁(yè),還剩3頁(yè)未讀 繼續(xù)免費(fèi)閱讀

付費(fèi)下載

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

【移動(dòng)應(yīng)用開發(fā)技術(shù)】AndroidStudio中通過CMake使用NDK并編譯自定義庫(kù)和添加預(yù)編譯庫(kù)

Note:這篇文章是基于AndroidStudio3.01版本的,NDK是R16。step1:創(chuàng)建一個(gè)包含C++的項(xiàng)目其他默認(rèn)就可以了。C++Standard指定編譯庫(kù)的環(huán)境,其中ToolchainDefault使用的是默認(rèn)的CMake環(huán)境;C++11也就是C++環(huán)境。兩種環(huán)境都可以編庫(kù),至于區(qū)別,后續(xù)會(huì)跟進(jìn),當(dāng)前博文使用的是CMake環(huán)境。ExceptionsSupport

如果選中復(fù)選框,則表示當(dāng)前項(xiàng)目支持C++異常處理,如果支持,在項(xiàng)目Module級(jí)別的build.gradle文件中會(huì)增加一個(gè)標(biāo)識(shí)-fexceptions到cppFlags屬性中,并且在so庫(kù)構(gòu)建時(shí),gradle會(huì)把該屬性值傳遞給CMake進(jìn)行構(gòu)建。RuntimeTypeInformationSupport

同理,選中復(fù)選框,項(xiàng)目支持RTTI,屬性cppFlags增加標(biāo)識(shí)-frtti切換到project模式,生成的目錄的結(jié)構(gòu)如下:3、認(rèn)識(shí)CMakeLists.txt構(gòu)建腳本文件CMakeLists.txt文件用于配置JNI項(xiàng)目屬性,主要用于聲明CMake使用版本、so庫(kù)名稱、C/CPP文件路徑等信息,下面是該文件內(nèi)容:cmake_minimum_required(VERSION3.4.1)CMake最小版本使用的是3.4.1。add_library()配置so庫(kù)信息(為當(dāng)前當(dāng)前腳本文件添加庫(kù))native-lib這個(gè)是聲明引用so庫(kù)的名稱,在項(xiàng)目中,如果需要使用這個(gè)so文件,引用的名稱就是這個(gè)。值得注意的是,實(shí)際上生成的so文件名稱是libnative-lib。當(dāng)Run項(xiàng)目或者build項(xiàng)目是,在Module級(jí)別的build文件下的intermediates\transforms\mergeJniLibs\debug\folders\2000\1f\main下會(huì)生成相應(yīng)的so庫(kù)文件。SHARED這個(gè)參數(shù)表示共享so庫(kù)文件,也就是在Run項(xiàng)目或者build項(xiàng)目時(shí)會(huì)在目錄intermediates\transforms\mergeJniLibs\debug\folders\2000\1f\main下生成so庫(kù)文。此外,so庫(kù)文件都會(huì)在打包到.apk里面,可以通過選擇菜單欄的Build->AnalyzeApk...*查看apk中是否存在so庫(kù)文件,一般它會(huì)存放在lib目錄下。src/main/cpp/native-lib.cpp構(gòu)建so庫(kù)的源文件。STATIC:靜態(tài)庫(kù),是目標(biāo)文件的歸檔文件,在鏈接其它目標(biāo)的時(shí)候使用。SHARED:動(dòng)態(tài)庫(kù),會(huì)被動(dòng)態(tài)鏈接,在運(yùn)行時(shí)被加載。MODULE:模塊庫(kù),是不會(huì)被鏈接到其它目標(biāo)中的插件,但是可能會(huì)在運(yùn)行時(shí)使用dlopen-系列的函數(shù)動(dòng)態(tài)鏈接。頭文件也可以配置頭文件路徑,方法是(注意這里指定的是目錄而非文件):下面的配置實(shí)際上與自定義的JNI項(xiàng)目(自定義的so庫(kù))沒有太大關(guān)系。find_library()這個(gè)方法與我們要?jiǎng)?chuàng)建的so庫(kù)無關(guān)而是使用NDK的Apis或者庫(kù),默認(rèn)情況下Android平臺(tái)集成了很多NDK庫(kù)文件,所以這些文件是沒有必要打包到apk里面去的。直接聲明想要使用的庫(kù)名稱即可(猜測(cè):貌似是在Sytem/libs目錄下)。在這里不需要指定庫(kù)的路徑,因?yàn)檫@個(gè)路徑已經(jīng)是CMake路徑搜索的一部分。如示例中使用的是log相關(guān)的so庫(kù)。log-lib這個(gè)指定的是在NDK庫(kù)中每個(gè)類型的庫(kù)會(huì)存放一個(gè)特定的位置,而log庫(kù)存放在log-lib中l(wèi)og指定使用log庫(kù)target_link_libraries()如果你本地的庫(kù)(native-lib)想要調(diào)用log庫(kù)的方法,那么就需要配置這個(gè)屬性,意思是把NDK庫(kù)關(guān)聯(lián)到本地庫(kù)。native-lib要被關(guān)聯(lián)的庫(kù)名稱${log-lib}要關(guān)聯(lián)的庫(kù)名稱,要用大括號(hào)包裹,前面還要有$符號(hào)去引用。實(shí)際上,我們可以自己創(chuàng)建CMakeLists.txt文件,而且路徑不受限制,只要在build.gradle中配置externalNativeBuild.cmake.path來指定該文件路徑即可。add_subdirectory可以執(zhí)行子路徑的CMakeLists.txt添加自定義的C++庫(kù)mathlib創(chuàng)建源文件我的項(xiàng)目名稱為OpenCVTest,所以右鍵這個(gè)項(xiàng)目點(diǎn)擊New->Module,然后選AndroidLibrary,輸入庫(kù)的名稱MathLib,然后Finish,系統(tǒng)就會(huì)生成對(duì)應(yīng)的模塊,并構(gòu)建好初始的目錄樹。系統(tǒng)將庫(kù)命名為MathLib,但是目錄樹中還是小寫的mathlib。這個(gè)時(shí)候系統(tǒng)會(huì)自動(dòng)在頂級(jí)settings.gradle添加對(duì)于這個(gè)新模塊的include語(yǔ)句。并且在模塊目錄下構(gòu)建好了初始的build.gradle。

現(xiàn)在我們開始創(chuàng)建自己的C++庫(kù),首先右鍵mathlib目錄下的src/main,然后選擇New->Directory,輸入cpp并確定。這個(gè)目錄就是我們要?jiǎng)?chuàng)建的庫(kù)的源文件的位置。

右鍵add,點(diǎn)擊New->C/C++SourceFile,輸入add.cpp,并選中Createanassociatedheader。

在.cpp文件中定義好一個(gè)簡(jiǎn)單的加法函數(shù),并在.h文件中添加好對(duì)應(yīng)聲明。

add.cpp將源文件關(guān)聯(lián)到構(gòu)建系統(tǒng)中我們用CMake來構(gòu)建C++庫(kù),然后CMake又要和gradle結(jié)合,在AndroidStudio里面協(xié)作管理C++和Java的代碼。

我們?cè)谀Kmathlib的根目錄下創(chuàng)建一個(gè)名為CMakeLists.txt的文件,寫入

set可以自定義變量。這里定義生成so文件的目錄

set_target_properties命令的意思是設(shè)置目標(biāo)的一些屬性來改變它們構(gòu)建的方式。這個(gè)命令中設(shè)置了add的ARCHIVE_OUTPUT_DIRECTORY屬性。也就是改變了輸出路徑。

add_custom_command命令是自定義命令。命令中把頭文件也復(fù)制到了distribution_DIR中。

target_include_directories,它對(duì)創(chuàng)建的庫(kù)設(shè)置include路徑,針對(duì)目標(biāo)來設(shè)置,可以避免與其他庫(kù)的沖突,并且此時(shí)對(duì)自定義的庫(kù)設(shè)置好了此路徑后,后續(xù)導(dǎo)入這個(gè)庫(kù)就不需要再次設(shè)置了。但對(duì)于預(yù)構(gòu)建的庫(kù),就需要設(shè)置,稍后會(huì)有詳細(xì)講解。

接下來我們?cè)谀Kmathlib的build.gradle中的defaultConfig{}中添加如下語(yǔ)句:

這里arguments是編譯參數(shù),而targets則是相比于add_subdirectory更高權(quán)限的方法。一般來說可以把它刪去,即默認(rèn)構(gòu)建所有目標(biāo)。

然后在android{}最后添加如下語(yǔ)句,將CMakeLists.txt關(guān)聯(lián)起來。

C++庫(kù)已經(jīng)創(chuàng)建好了,接下來就要在主模塊中使用它了。為了使用自定義C++庫(kù),我們需要一個(gè)中間人,它從Android本身的Java程序中獲取請(qǐng)求,然后使用我們的C++庫(kù)中的函數(shù)計(jì)算得到結(jié)果,并將數(shù)據(jù)傳回Android本身的Java程序中。創(chuàng)建一個(gè)中間文件native-math.cpp在app/CMakeLists.txt加上這個(gè)自定義庫(kù)的引用

在模塊app的局部build.gradle中,像之前一樣添加好對(duì)應(yīng)的語(yǔ)句:defaultConfig{}中:其中ndk指定abi平臺(tái)

ABI(Applicationbinaryinterface)應(yīng)用程序二進(jìn)制接口。不同的CPU與指令集的每種組合都有定義的ABI(應(yīng)用程序二進(jìn)制接口),一段程序只有遵循這個(gè)接口規(guī)范才能在該CPU上運(yùn)行,所以同樣的程序代碼為了兼容多個(gè)不同的CPU,需要為不同的ABI構(gòu)建不同的庫(kù)文件。當(dāng)然對(duì)于CPU來說,不同的架構(gòu)并不意味著一定互不兼容。armeabi設(shè)備只兼容armeabi;

armeabi-v7a設(shè)備兼容armeabi-v7a、armeabi;

arm64-v8a設(shè)備兼容arm64-v8a、armeabi-v7a、armeabi;

X86設(shè)備兼容X86、armeabi;

X86_64設(shè)備兼容X86_64、X86、armeabi;

mips64設(shè)備兼容mips64、mips;

mips只兼容mips;

接著在src/main/java/*/MainActivity.java中的MainActivity類下面,加載庫(kù),以及設(shè)置好對(duì)應(yīng)的方法聲明:然后就可以在onCreate方法中使用這個(gè)C++庫(kù)定義的函數(shù),在Java中對(duì)應(yīng)的函數(shù)了

最后別忘了在項(xiàng)目中添加模塊的依賴關(guān)系才可以正常運(yùn)行這個(gè)AndroidApp。右鍵項(xiàng)目OpenCVTest,選擇OpenModuleSettings。選擇app->Dependencies,添加Moduledependency,選擇mathlib,確定即可添加OpenCV庫(kù)的支持導(dǎo)入OpenCV進(jìn)項(xiàng)目從OpenCV的官網(wǎng)將OpenCV4Android3.4下載下來,解壓到某個(gè)目錄。

點(diǎn)擊AndroidStudio的File->New->ImportModule,然后選擇路徑為OpenCV-android-sdk/sdk/java,確定。并在導(dǎo)入之后,修改build.gradle中的SDK版本。

在OpenModuleSettings中添加模塊的依賴關(guān)系,使app依賴openCVLibrary340。現(xiàn)在已經(jīng)可以在.java文件中看得到OpenCV的自動(dòng)補(bǔ)全了。配置OpenCV的C++預(yù)構(gòu)建庫(kù)把包含文件夾OpenCV-android-sdk/sdk/native/jni/include和預(yù)構(gòu)建庫(kù)文件夾OpenCV-android-sdk/sdk/native/libs也復(fù)制到項(xiàng)目的distribution中。由于之前已經(jīng)在添加C++庫(kù)時(shí)修改了app的build.gradle,所以這個(gè)步驟現(xiàn)在不需要再執(zhí)行了。由于OpenCV是預(yù)構(gòu)建庫(kù),所以沒有編譯的過程,因此模塊openCVLibrary320中不需要添加CMakeLists.txt等。我們直接在app模塊中根目錄下的CMakeLists.txt導(dǎo)入OpenCV的庫(kù)即可。需要注意的是.so使用SHARED,.a使用STATIC。注意:預(yù)構(gòu)建庫(kù):so文件和.a文件必須copy在src/main/jniLibs這個(gè)目錄,才

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論