前言
有一些人反映在github上下載的專案或者作為module匯入你的專案中,執行不起來。或者幾經折騰才勉強執行起來,不知道你有沒有這種感覺,如果你有這種困惑不妨繼續閱讀下文,相信本文能幫到你。我一直認為從github或者網上搜尋到自己需要的案例,下載下來並且能快速執行起來是作為一個Android開發者最基本的能力要求,可能挖的坑多了以後,已經懂得去處理了吧。只能說github上的專案除了一些專案本身提交不完整,實在是缺三拉四的,其餘百分之九十九點九都是可以正常執行的。在如何快速執行一個github的demo之前,先來講解下Android Studio中gradle的一些玩法。
Android Studio專案中兩種gradle檔案
1.根目錄的build.gradle
新建一個Android Studio專案,根目錄會自動生成一個build.gradle檔案,主要是配置一些外掛和預設的依賴類庫的倉庫。
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
}複製程式碼
2.module中的根目錄的build.gradle
Android Studio這個IDE不同於eclipse,eclipse啟動開啟的是工作空間,一個工作空間下可以包括零個多個工程專案。而Android Studio則是單個工程專案啟動,一個工程專案中包括一個或多個module,其中有一個build.gradle檔案中頭部為apply plugin: 'com.android.application'標識的為應用程式module,其餘以apply plugin: 'com.android.library'標識為Android Library。在編譯的時候,所有module的build.gradle依賴的類庫都會合併為一個。
主程式的build.gradle檔案
apply plugin: 'com.android.application'//作為主程式的標識
android {
compileSdkVersion 24//當前向前相容sdk的版本
buildToolsVersion "24.0.3"//構建工具的版本
defaultConfig {
applicationId "com.dou361.demogradle"//應用程式的id,在市場上使用的包名
minSdkVersion 15//最小sdk版本支援
targetSdkVersion 24//目標sdk版本
versionCode 1//應用程式版本號
versionName "1.0"//應用程式版本名稱
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false//混淆是否開啟
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {//依賴外部的類庫
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:24.2.1'
testCompile 'junit:junit:4.12'
}複製程式碼
sdk版本設定規則
minSdkVersion <= targetSdkVersion <= compileSdkVersion
minSdkVersion <= buildToolsVersion <= compileSdkVersion複製程式碼
Android Library中的build.gradle檔案
apply plugin: 'com.android.library'
android {
compileSdkVersion 24
buildToolsVersion "24.0.3"
defaultConfig {
minSdkVersion 15
targetSdkVersion 24
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:24.2.1'
testCompile 'junit:junit:4.12'
}複製程式碼
gradle的一些玩法
1.全域性變數的使用
不知道你有沒有注意到,在多個module的情況下,不同module的build.gradle檔案中有部分配置項類似,或者依賴的類庫,有部分是相同的,在維護上不是很方便,這個時候就可以考慮統一配置。在專案根目錄的build.gradle檔案中新增以下程式碼和android{}同級
ext {
//全域性變數控制,可在module中的build.gradle檔案通過rootProject.ext.xxx開頭來使用
compileSdkVersion = 24
buildToolsVersion = '24.0.3'
supportVersion = '24.2.1'
//主程式版本
targetSdkVersion = 24
minSdkVersion = 15
versionCode = 1
versionName = "v1.0.0"
//library版本
jjdxm_minSdkVersion = 9
jjdxm_versionCode = 1
jjdxm_versionName = "v1.0.0"
jjdxm_v4 = 'com.android.support:support-v4:'+supportVersion
jjdxm_v7 = 'com.android.support:appcompat-v7:'+supportVersion
jjdxm_design = 'com.android.support:design:'+supportVersion
jjdxm_cardview = 'com.android.support:cardview:'+supportVersion
jjdxm_recyclerview = 'com.android.support:recyclerview-v7:'+supportVersion
}複製程式碼
全域性變數控制,可在module中的build.gradle檔案通過rootProject.ext.xxx開頭來使用,在所有module的build.gradle檔案中配置以上變數,以後在維護專案的時候,只需要在根目錄這個檔案中修改對應的配置項即可是不是很簡單,可能當前你還覺得這樣配置很麻煩,在使用AS過程中相信大家都遇到過架包衝突的情況,例如主程式中依賴了com.android.support:appcompat-v7:23.3.0,而其他module中依賴com.android.support:appcompat-v7:24.2.1的版本,這個時候就會引起衝突,而通過上面的全域性配置,只需要在所有的module中配置上rootProject.ext.jjdxm_v7就都統一了不僅解決了衝突問題,而且可以隨意切換不同版本的v7類庫。
2.配置打包用的簽名
主要有接過分享或者授權登入功能的都應該知道,像微信或者微博的分享和授權登入提供sdk,只有在指定的簽名下才能生效,而我們平時開發都習慣使用預設的androidkeystore打包簽名,這個時候想要測試分享或者登入功能就需要手動去打包指定keystore的簽名。非常影響開發效率,這個時候可以通過配置gradle,根據release或者是debug打包指定的簽名。
專案根目錄新建一個簽名用到的密碼管理檔案signing.properties
signing.alias=dou361 #release
signing.password=dou361 #release
signing.jjdxm_alias=dou361 #debug
signing.jjdxm_password=dou361 #debug複製程式碼
在主程式build.gradle的apply plugin: 'com.android.application'下面新增
Properties props = new Properties()
props.load(new FileInputStream(file(rootProject.file("signing.properties"))))複製程式碼
在android{}節點裡面新增
signingConfigs {
release {
keyAlias props['signing.alias']
keyPassword props['signing.password']
storeFile file(rootProject.file("debug.keystore"))
storePassword props['signing.password']
}
debug {
keyAlias props['signing.jjdxm_alias']
keyPassword props['signing.jjdxm_password']
storeFile file(rootProject.file("debug.keystore"))
storePassword props['signing.jjdxm_password']
}
}
buildTypes {
debug {
signingConfig signingConfigs.debug
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
release {
signingConfig signingConfigs.release
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}複製程式碼
最後所有檔案如下
根目錄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()
}
}
ext {
//全域性變數控制,可在module中的build.gradle檔案通過rootProject.ext.xxx開頭來使用
compileSdkVersion = 24
buildToolsVersion = '24.0.3'
supportVersion = '24.2.1'
//主程式版本
targetSdkVersion = 24
minSdkVersion = 15
versionCode = 1
versionName = "v1.0.0"
//library版本
jjdxm_minSdkVersion = 9
jjdxm_versionCode = 1
jjdxm_versionName = "v1.0.0"
jjdxm_v4 = 'com.android.support:support-v4:'+supportVersion
jjdxm_v7 = 'com.android.support:appcompat-v7:'+supportVersion
jjdxm_design = 'com.android.support:design:'+supportVersion
jjdxm_cardview = 'com.android.support:cardview:'+supportVersion
jjdxm_recyclerview = 'com.android.support:recyclerview-v7:'+supportVersion
}
task clean(type: Delete) {
delete rootProject.buildDir
}複製程式碼
主程式的build.gradle
apply plugin: 'com.android.application'
Properties props = new Properties()
props.load(new FileInputStream(file(rootProject.file("signing.properties"))))
android {
signingConfigs {
release {
keyAlias props['signing.alias']
keyPassword props['signing.password']
storeFile file(rootProject.file("debug.keystore"))
storePassword props['signing.password']
}
debug {
keyAlias props['signing.jjdxm_alias']
keyPassword props['signing.jjdxm_password']
storeFile file(rootProject.file("debug.keystore"))
storePassword props['signing.jjdxm_password']
}
}
compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
defaultConfig {
applicationId "com.dou361.demogradle"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode rootProject.ext.versionCode
versionName rootProject.ext.versionName
multiDexEnabled true
ndk {
// 指定要ndk需要相容的架構(這樣其他依賴包裡mips,x86,armeabi,arm-v8之類的so會被過濾掉)
abiFilters "armeabi-v7a", "armeabi"
}
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
debug {
signingConfig signingConfigs.debug
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
release {
signingConfig signingConfigs.release
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
repositories { flatDir { dirs 'libs' } }
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
testCompile 'junit:junit:4.12'
compile rootProject.ext.jjdxm_v7
compile rootProject.ext.jjdxm_design
}複製程式碼
其他module的build.gradle
apply plugin: 'com.android.library'
android {
compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
defaultConfig {
minSdkVersion rootProject.ext.jjdxm_minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode rootProject.ext.jjdxm_versionCode
versionName rootProject.ext.jjdxm_versionName
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
testCompile 'junit:junit:4.12'
compile rootProject.ext.jjdxm_v7
compile rootProject.ext.jjdxm_design
}複製程式碼
keystore密碼管理檔案signing.properties
signing.alias=dou361
signing.password=dou361
signing.jjdxm_alias=dou361
signing.jjdxm_password=dou361複製程式碼
github上專案下載執行
之所以先介紹gradle的一些配置,是因為一個AS專案的啟動基本上都是在根據gradle檔案裡面的配置去聯網同步內容下來的。先了解gradle的一些配置和具體的用法以後會比較容易理解。其中類庫內容同步失敗、架包衝突、sdk版本等問題都可能會導致專案執行不起來。所以從github上面下載下來的專案,不要著急立馬開啟專案,要是網路不好你會發現一隻卡在同步中的介面,這個是因為不同開發者環境不盡相同導致的。
既然開發環境不同,那就可以考慮修改為自己已有的環境,可以省去大部分聯網同步操作,在網路差的情況是很明智的一個舉動,主要有以下幾個步驟:
1.先修改根目錄的build.gradle配置
根目錄裡面無非就一個gradle版本的差異,修改為你當前已有的版本,例如下載的demo是
classpath 'com.android.tools.build:gradle:2.2.3'複製程式碼
版本號2.2.3,而你的環境只有2.1.0的,那就可以修改為
classpath 'com.android.tools.build:gradle:2.1.0'複製程式碼
版本跨越不大的情況下,可以採用以上做法,如果有部分方法不可用,則還是建議聯網下載,一勞永逸。
2.module目錄中的build.gradle配置
大部分module都會依賴到v4 v7等一些support家族的類庫,這個時候有兩種情況會導致出問題,一是module之間的v4包版本號不一致,二是v4版本你的環境沒有。
針對第一種情況,匯入別人的module到你的專案中經常會遇到,解決辦法是參考上面的配置全域性的依賴或者移除重複的;
針對第二種情況,開啟別人的專案經常會遇到,解決辦法是修為你環境已有的版本或者聯網同步下載。
修改完所有module的build.gradle檔案以後,這個時候在開啟專案,有個別不存在類庫會同步去下載,完成以後基本上都是可以執行起來的。