Android游戲開發(fā)實(shí)踐(1)之NDK與JNI開發(fā)03
前面已經(jīng)分享了兩篇有關(guān)Android平臺(tái)NDK與JNI開發(fā)相關(guān)的內(nèi)容免绿。以下列舉前面兩篇的鏈接地址葵姥,感興趣的可以再回顧下驶兜。那么刁岸,這篇繼續(xù)這個(gè)小專題塞颁,主要分享下AndroidStudio下的NDK與JNI開發(fā)的相關(guān)操作以及簡(jiǎn)述下CMake的使用走贪。最后,會(huì)以一個(gè)實(shí)例來(lái)結(jié)束這個(gè)小專題的分享缰盏,那個(gè)涌萤,就放在最后一篇吧。
傳送門:
Android游戲開發(fā)實(shí)踐(1)之NDK與JNI開發(fā)01
Android游戲開發(fā)實(shí)踐(1)之NDK與JNI開發(fā)02
本文的目錄如下:
- 1口猜、環(huán)境搭建
- 2形葬、創(chuàng)建一個(gè)支持C/C++的項(xiàng)目
- 2.1 新建項(xiàng)目
- 2.2 擴(kuò)展現(xiàn)有項(xiàng)目
- 3、AndroidStudio與Gradle
- 3.1 project/build.gradle
- 3.2 project/settings.gradle
- 3.3 module/build.gradle
<h3 id="get-start">1暮的、 環(huán)境搭建</h3>
要讓AndroidStudio支持NDK開發(fā)笙以,除了需安裝AndroidStudio2.2以上的版本。還得安裝NDK
冻辩、CMake
猖腕、LLDB
等工具拆祈。
在AndroidStudio中選擇Tools->Android->SDK Manager->SDK Tools。如圖:
這里簡(jiǎn)單介紹下:
NDK
:是Android開發(fā)本地C/C++代碼的一套工具集倘感。
CMake
:一套跨平臺(tái)的構(gòu)建工具放坏,可以Gradle腳本配合使用來(lái)構(gòu)建你的本地庫(kù)。在AndroidStudio中老玛,Google默認(rèn)和推薦使用CMake進(jìn)行編譯淤年,當(dāng)然,你仍然可以繼續(xù)使用ndk-build
來(lái)編譯你的本地代碼蜡豹。注意:32位的操作系統(tǒng)可能會(huì)裝不上麸粮。
LLDB
: 一種調(diào)試器,Android Studio中可以使用它來(lái)調(diào)試本地代碼镜廉。
<h3 id="new-project">2弄诲、 創(chuàng)建一個(gè)支持C/C++的項(xiàng)目</h3>
這里所說的創(chuàng)建一個(gè)支持C/C++的項(xiàng)目,可以理解為創(chuàng)建一個(gè)NDK項(xiàng)目娇唯,但又包含兩種方式齐遵,分別是從零開始新建一個(gè)支持C/C++開發(fā)的項(xiàng)目和在原有項(xiàng)目的基礎(chǔ)上讓它支持C/C++開發(fā)。下面對(duì)這兩種方式分別進(jìn)行說明下塔插。
<h5 id="new-project1">2.1 新建項(xiàng)目</h5>
如果安裝好了梗摇,上面介紹的幾個(gè)工具(主要是NDK),并且AndroidStudio2.2以上的版本想许,新建項(xiàng)目的時(shí)候伶授,會(huì)看到這個(gè)選項(xiàng)。如圖:
創(chuàng)建項(xiàng)目時(shí)伸刃,勾選C++支持。
項(xiàng)目中所用的C++標(biāo)準(zhǔn)可以選擇默認(rèn)或者支持C++11逢倍,以及是否支持異常和
rtti
特性捧颅。
創(chuàng)建完項(xiàng)目,會(huì)比一般的Android項(xiàng)目多出cpp目錄以及CMakeLists.txt的文件较雕。
這里指定NDK的路徑碉哑。即,上面環(huán)境搭建里安裝的ndk亮蒋,會(huì)下載到AndroidStudio根目錄下的
ndk-bundle
文件夾中扣典。
make一下當(dāng)前新創(chuàng)建的工程,默認(rèn)會(huì)在build/cmake/debug/obj/下生成相應(yīng)的動(dòng)態(tài)庫(kù)慎玖。
<h5 id="new-project2">2.2 擴(kuò)展現(xiàn)有項(xiàng)目</h5>
要讓現(xiàn)有的Android項(xiàng)目能調(diào)用本地C/C++代碼或者支持C/C++開發(fā)贮尖,只需要在原來(lái)項(xiàng)目的基礎(chǔ)稍加修改即可。步驟如下:
切換到project視圖趁怔,打開module即上圖的app模塊湿硝,在src/main下右鍵New->Directory薪前,填寫一個(gè)文件名,例如:
cpp
关斜。
在剛建的cpp路徑下示括,右鍵New->C/C++ Source File,輸入文件名痢畜,若要一并生成相應(yīng)的
.h
文件垛膝,勾選Create an associated header選項(xiàng)即可。注意丁稀,后面可以指定源文件的后綴吼拥,例如:.cxx
,.hxx
。
在module的根目錄即上圖的app根目錄二驰,右鍵New->File扔罪,輸入
CMakeLists.txt
。注意:文件名必須為CMakeLists.txt
在module的根目錄即上圖的app根目錄桶雀,選擇Link C++ Project with Gradle矿酵,然后,找到剛創(chuàng)建的
CMakeLists.txt
文件矗积。將CMakeLists.txt
關(guān)聯(lián)到項(xiàng)目中全肮。注意,Build System仍可以選擇ndk-build
方式進(jìn)行編譯棘捣。
當(dāng)然辜腺,這步操作也可以手動(dòng)完成,相當(dāng)于在當(dāng)前module下的build.gradle腳本中乍恐,添加了如下代碼评疗,
android {
//指定使用CMake編譯----------------
externalNativeBuild {
cmake {
path 'CMakeLists.txt'
}
}
//--------------------------------
}
打開新建的CMakeLists.txt
文件,輸入如下代碼:
cmake_minimum_required (VERSION 3.4.1)
add_library (hellojni SHARED src/main/cpp/hellojni.cpp)
分別指定CMake要求的版本茵烈,add_library中參數(shù)分別是百匆,指定生成庫(kù)的名稱,生成庫(kù)的類型呜投,默認(rèn)是靜態(tài)塊加匈,即:·a
,源碼的路徑仑荐。這里實(shí)例只簡(jiǎn)單介紹下CMake的用法雕拼,后續(xù)會(huì)有專門一篇來(lái)介紹下CMake更多高級(jí)的用法。
以上完畢粘招,在make一下當(dāng)前工程啥寇,或者rebuild一下,不出意外會(huì)在build/intermediates/cmake/debug
路徑下生成各種libhellojni.so
文件。
<h3 id="as-gradle">3示姿、AndroidStudio與Gradle</h3>
上面提到甜橱,將CMakeLists.txt關(guān)聯(lián)到項(xiàng)目中,會(huì)在build.gradle腳本中栈戳,添加一段代碼即可岂傲。可能剛接觸AndroidStudio(特別是使用其它IDE開發(fā)的子檀,例如:eclipse等)對(duì)Gradle不是很了解镊掖,這里就拋磚引玉下,簡(jiǎn)要講述下gradle腳本的使用褂痰。
首先亩进,AndroidStudio是基于IntelliJ IDEA的IDE,在AndroidStudio中新創(chuàng)建的Android工程都形如如下結(jié)構(gòu):
MyApp
├── build.gradle
├── settings.gradle
└── app
├── build.gradle
├── build
├── libs
└── src
└── main
├── java
│ └── com.package.myapp
└── res
├── drawable
├── layout
└── etc.
MyApp是項(xiàng)目名缩歪,app是模塊名归薛,一個(gè)項(xiàng)目下可以包含若干個(gè)模塊。這與eclipse的結(jié)構(gòu)不同匪蝙,對(duì)應(yīng)到eclipse中主籍,app就相當(dāng)于項(xiàng)目名,MyApp相當(dāng)于工作空間逛球∏г或者類似于VS中解決方案與項(xiàng)目的關(guān)系。以上目錄結(jié)構(gòu)關(guān)系颤绕,并不與實(shí)際磁盤上的目錄結(jié)構(gòu)對(duì)應(yīng)幸海。可以看到奥务,在項(xiàng)目根目錄下以及模塊目錄下物独,分別有三個(gè).gradle
文件。下面氯葬,就分別介紹這三個(gè)gradle腳本的用途挡篓,當(dāng)然這里主要說的是在AndroidStudio下的gradle的相關(guān)使用。
在AndroidStudio中android項(xiàng)目是基于gradle進(jìn)行構(gòu)建的(eclipse中可以使用ant來(lái)做類似的工作)溢谤,而gradle是一種基于Groovy語(yǔ)言的DSL(domain-specific language瞻凤,領(lǐng)域?qū)S谜Z(yǔ)言)憨攒,而Groovy又是一種基于JVM的動(dòng)態(tài)語(yǔ)言世杀。所以,有java基礎(chǔ)的話肝集,理解Groovy會(huì)更容易瞻坝。有關(guān)Gradle文檔可以看看這個(gè):
https://docs.gradle.org/current/dsl/
<h5 id="project-build">3.1 project/build.gradle</h5>
該build.gradle位于項(xiàng)目的根目錄,該文件是定義在這個(gè)工程下的所有模塊的公共屬性。默認(rèn)如下:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.3'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
以下只是從表象說明下所刀,但實(shí)質(zhì)是Groovy相應(yīng)的數(shù)據(jù)結(jié)構(gòu)(閉包衙荐,Map等)調(diào)用相應(yīng)方法來(lái)動(dòng)態(tài)控制整個(gè)構(gòu)建過程。有關(guān)Groovy的討論可以看看3.3 module/build.gradle浮创。
buildscript
:定義了全局的相關(guān)屬性忧吟。
repositories
:定義了遠(yuǎn)程倉(cāng)庫(kù)的源,即代表你的依賴包的來(lái)源斩披。這里將jcenter()作為倉(cāng)庫(kù)溜族。
dependencies
:定義了android gradle plugin的版本。
allprojects
:可以用來(lái)定義各個(gè)模塊的默認(rèn)屬性垦沉,你可以不僅僅局限于默認(rèn)的配置煌抒,未來(lái)你可以自己創(chuàng)造tasks在allprojects方法體內(nèi),這些tasks將會(huì)在所有模塊中可見厕倍。
task clean
:執(zhí)行相關(guān)的清理任務(wù)寡壮。
<h5 id="as-settings">3.2 project/settings.gradle</h5>
該文件位于項(xiàng)目根目錄下,也是項(xiàng)目的全局配置文件讹弯,該文件的內(nèi)容如下:
include ':app'
如果况既,你的項(xiàng)目中有多個(gè)模塊時(shí),可以依次添加到該文件中闸婴。例如:
include ':app',':librarys:Mylibrary'
即在項(xiàng)目根目錄下的librarys目錄里有個(gè)Mylibrary庫(kù)工程坏挠。
<h5 id="as-module">3.3 module/build.gradle</h5>
該文件位于當(dāng)前模塊的根目錄下,通常情況下邪乍,該文件只對(duì)當(dāng)前模塊起作用降狠。例如:
apply plugin: 'com.android.application'
android {
compileSdkVersion 24
buildToolsVersion "24.0.2"
defaultConfig {
applicationId "com.alphagl.test"
minSdkVersion 19
targetSdkVersion 24
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
externalNativeBuild {
cmake {
path 'CMakeLists.txt'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:24.2.1'
}
以上內(nèi)容,要徹底弄清楚庇楞,得深究下Groovy語(yǔ)法榜配。這里,只淺析下。
apply plugin: 'com.android.application':在Groovy中的調(diào)用為project.apply([plugin: 'com.android.application'])畴博,plugin: 'com.android.application
會(huì)被作為一個(gè)Map參數(shù)傳遞給apply的方法可很。這里是要將該模塊構(gòu)建為一個(gè)應(yīng)用,若要將模塊構(gòu)建庫(kù)形式烙心,可以傳參為plugin: 'com.android.library
。
在Groovy中花括號(hào)包含的部分稱為一個(gè)閉包(Closure)乏沸。上面的主要兩部分android和dependencies淫茵,分別對(duì)應(yīng)project中的方法,而參數(shù)是相應(yīng)的閉包結(jié)構(gòu)蹬跃。通過上面的結(jié)構(gòu)匙瘪,可以知道該閉包結(jié)構(gòu)還有閉包嵌套和相應(yīng)的方法。
android:該方法包含了所有的Android屬性,而唯一必須包含屬性為compileSdkVersion和buildToolsVersion丹喻。
compileSdkVersion:該方法包含編譯該app時(shí)候薄货,使用到的api版本。
buildToolsVersion:該方法包含構(gòu)建工具的版本號(hào)碍论。
defaultConfig:該方法包含app的核心屬性谅猾,該屬性會(huì)覆蓋在AndroidManifest.xml中的對(duì)應(yīng)屬性。
applicationId:該方法定義的屬性會(huì)覆蓋AndroidManifest文件中的包名package name屬性鳍悠。
minSdkVersion:該方法定義的屬性表示最小支持api版本赊瞬。同AndroidManifest中對(duì)應(yīng)的屬性。
targetSdkVersion:該方法定義的屬性表示目標(biāo)平臺(tái)api版本贼涩。同AndroidManifest中對(duì)應(yīng)的屬性巧涧。
buildTypes:該方法定義了構(gòu)建不同版本的app相關(guān)的屬性。
release:配置release版本相關(guān)的屬性遥倦。
minifyEnabled:是否進(jìn)行混淆谤绳。
proguardFiles:定義混淆文件的位置。通過getDefaultProguardFile方法獲取袒哥。
externalNativeBuild:native使用cmake編譯缩筛。
dependencies:gradle默認(rèn)的屬性之一,定義了所有的依賴包堡称。
compile:編譯相應(yīng)依賴的jar包瞎抛。組織名,包名却紧,版本號(hào)的結(jié)構(gòu)桐臊。
以上只簡(jiǎn)單的列舉了下部分屬性,對(duì)gradle腳本有初步的了解晓殊。當(dāng)然断凶,Groovy在java領(lǐng)域還是有很多應(yīng)用的。感興趣的巫俺,可以深入了解下认烁。
Groovy文檔:
Groovy-Documentation