Android游戲開發實踐(1)之NDK與JNI開發03 前面已經分享了兩篇有關Android平臺NDK與JNI開發相關的內容。以下列舉前面兩篇的鏈接地址,感興趣的可以再回顧下。那麼,這篇繼續這個小專題,主要分享下AndroidStudio下的NDK與JNI開發的相關操作以及簡述下CMake的使用。 ...
Android游戲開發實踐(1)之NDK與JNI開發03
前面已經分享了兩篇有關Android平臺NDK與JNI開發相關的內容。以下列舉前面兩篇的鏈接地址,感興趣的可以再回顧下。那麼,這篇繼續這個小專題,主要分享下AndroidStudio下的NDK與JNI開發的相關操作以及簡述下CMake的使用。最後,會以一個實例來結束這個小專題的分享,那個,就放在最後一篇吧。
作者:AlphaGL。版權所有,歡迎保留原文鏈接進行轉載 :)
傳送門:
Android游戲開發實踐(1)之NDK與JNI開發01
Android游戲開發實踐(1)之NDK與JNI開發02
本文的目錄如下:
1、 環境搭建
要讓AndroidStudio支持NDK開發,除了需安裝AndroidStudio2.2以上的版本。還得安裝NDK
、CMake
、LLDB
等工具。
在AndroidStudio中選擇Tools->Android->SDK Manager->SDK Tools。如圖:
這裡簡單介紹下:
NDK
:是Android開發本地C/C++代碼的一套工具集。
CMake
:一套跨平臺的構建工具,可以Gradle腳本配合使用來構建你的本地庫。在AndroidStudio中,Google預設和推薦使用CMake進行編譯,當然,你仍然可以繼續使用ndk-build
來編譯你的本地代碼。註意:32位的操作系統可能會裝不上。
LLDB
: 一種調試器,Android Studio中可以使用它來調試本地代碼。
2、 創建一個支持C/C++的項目
這裡所說的創建一個支持C/C++的項目,可以理解為創建一個NDK項目,但又包含兩種方式,分別是從零開始新建一個支持C/C++開發的項目和在原有項目的基礎上讓它支持C/C++開發。下麵對這兩種方式分別進行說明下。
2.1 新建項目
如果安裝好了,上面介紹的幾個工具(主要是NDK),並且AndroidStudio2.2以上的版本,新建項目的時候,會看到這個選項。如圖:
創建項目時,勾選C++支持。
項目中所用的C++標準可以選擇預設或者支持C++11,以及是否支持異常和rtti
特性。
創建完項目,會比一般的Android項目多出cpp目錄以及CMakeLists.txt的文件。
這裡指定NDK的路徑。即,上面環境搭建里安裝的ndk,會下載到AndroidStudio根目錄下的ndk-bundle
文件夾中。
make一下當前新創建的工程,預設會在build/cmake/debug/obj/下生成相應的動態庫。
2.2 擴展現有項目
要讓現有的Android項目能調用本地C/C++代碼或者支持C/C++開發,只需要在原來項目的基礎稍加修改即可。步驟如下:
切換到project視圖,打開module即上圖的app模塊,在src/main下右鍵New->Directory,填寫一個文件名,例如:cpp
。
在剛建的cpp路徑下,右鍵New->C/C++ Source File,輸入文件名,若要一併生成相應的.h
文件,勾選Create an associated header選項即可。註意,後面可以指定源文件的尾碼,例如:.cxx
,.hxx
。
在module的根目錄即上圖的app根目錄,右鍵New->File,輸入CMakeLists.txt
。註意:文件名必須為CMakeLists.txt
在module的根目錄即上圖的app根目錄,選擇Link C++ Project with Gradle,然後,找到剛創建的CMakeLists.txt
文件。將CMakeLists.txt
關聯到項目中。註意,Build System仍可以選擇ndk-build
方式進行編譯。
當然,這步操作也可以手動完成,相當於在當前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中參數分別是,指定生成庫的名稱,生成庫的類型,預設是靜態塊,即:·a
,源碼的路徑。這裡實例只簡單介紹下CMake的用法,後續會有專門一篇來介紹下CMake更多高級的用法。
以上完畢,在make一下當前工程,或者rebuild一下,不出意外會在build/intermediates/cmake/debug
路徑下生成各種libhellojni.so
文件。
3、AndroidStudio與Gradle
上面提到,將CMakeLists.txt關聯到項目中,會在build.gradle腳本中,添加一段代碼即可。可能剛接觸AndroidStudio(特別是使用其它IDE開發的,例如:eclipse等)對Gradle不是很瞭解,這裡就拋磚引玉下,簡要講述下gradle腳本的使用。
首先,AndroidStudio是基於IntelliJ IDEA的IDE,在AndroidStudio中新創建的Android工程都形如如下結構:
MyApp
├── build.gradle
├── settings.gradle
└── app
├── build.gradle
├── build
├── libs
└── src
└── main
├── java
│ └── com.package.myapp
└── res
├── drawable
├── layout
└── etc.
MyApp是項目名,app是模塊名,一個項目下可以包含若幹個模塊。這與eclipse的結構不同,對應到eclipse中,app就相當於項目名,MyApp相當於工作空間。或者類似於VS中解決方案與項目的關係。以上目錄結構關係,並不與實際磁碟上的目錄結構對應。可以看到,在項目根目錄下以及模塊目錄下,分別有三個.gradle
文件。下麵,就分別介紹這三個gradle腳本的用途,當然這裡主要說的是在AndroidStudio下的gradle的相關使用。
在AndroidStudio中android項目是基於gradle進行構建的(eclipse中可以使用ant來做類似的工作),而gradle是一種基於Groovy語言的DSL(domain-specific language,領域專用語言),而Groovy又是一種基於JVM的動態語言。所以,有java基礎的話,理解Groovy會更容易。有關Gradle文檔可以看看這個:
https://docs.gradle.org/current/dsl/
3.1 project/build.gradle
該build.gradle位於項目的根目錄,該文件是定義在這個工程下的所有模塊的公共屬性。預設如下:
// 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
}
以下只是從表象說明下,但實質是Groovy相應的數據結構(閉包,Map等)調用相應方法來動態控制整個構建過程。有關Groovy的討論可以看看3.3 module/build.gradle。
buildscript
:定義了全局的相關屬性。
repositories
:定義了遠程倉庫的源,即代表你的依賴包的來源。這裡將jcenter()作為倉庫。
dependencies
:定義了android gradle plugin的版本。
allprojects
:可以用來定義各個模塊的預設屬性,你可以不僅僅局限於預設的配置,未來你可以自己創造tasks在allprojects方法體內,這些tasks將會在所有模塊中可見。
task clean
:執行相關的清理任務。
3.2 project/settings.gradle
該文件位於項目根目錄下,也是項目的全局配置文件,該文件的內容如下:
include ':app'
如果,你的項目中有多個模塊時,可以依次添加到該文件中。例如:
include ':app',':librarys:Mylibrary'
即在項目根目錄下的librarys目錄里有個Mylibrary庫工程。
3.3 module/build.gradle
該文件位於當前模塊的根目錄下,通常情況下,該文件只對當前模塊起作用。例如:
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'
}
以上內容,要徹底弄清楚,得深究下Groovy語法。這裡,只淺析下。
apply plugin: 'com.android.application':在Groovy中的調用為project.apply([plugin: 'com.android.application']),plugin: 'com.android.application
會被作為一個Map參數傳遞給apply的方法。這裡是要將該模塊構建為一個應用,若要將模塊構建庫形式,可以傳參為plugin: 'com.android.library
。
在Groovy中花括弧包含的部分稱為一個閉包(Closure)。上面的主要兩部分android和dependencies,分別對應project中的方法,而參數是相應的閉包結構。通過上面的結構,可以知道該閉包結構還有閉包嵌套和相應的方法。
android:該方法包含了所有的Android屬性,而唯一必須包含屬性為compileSdkVersion和buildToolsVersion。
compileSdkVersion:該方法包含編譯該app時候,使用到的api版本。
buildToolsVersion:該方法包含構建工具的版本號。
defaultConfig:該方法包含app的核心屬性,該屬性會覆蓋在AndroidManifest.xml中的對應屬性。
applicationId:該方法定義的屬性會覆蓋AndroidManifest文件中的包名package name屬性。
minSdkVersion:該方法定義的屬性表示最小支持api版本。同AndroidManifest中對應的屬性。
targetSdkVersion:該方法定義的屬性表示目標平臺api版本。同AndroidManifest中對應的屬性。
buildTypes:該方法定義了構建不同版本的app相關的屬性。
release:配置release版本相關的屬性。
minifyEnabled:是否進行混淆。
proguardFiles:定義混淆文件的位置。通過getDefaultProguardFile方法獲取。
externalNativeBuild:native使用cmake編譯。
dependencies:gradle預設的屬性之一,定義了所有的依賴包。
compile:編譯相應依賴的jar包。組織名,包名,版本號的結構。
以上只簡單的列舉了下部分屬性,對gradle腳本有初步的瞭解。當然,Groovy在java領域還是有很多應用的。感興趣的,可以深入瞭解下。
Groovy文檔:
Groovy-Documentation
技術交流QQ群:528655025
作者:AlphaGL
出處:http://www.cnblogs.com/alphagl/
版權所有,歡迎保留原文鏈接進行轉載 :)