前言
為啥要起這個名字呢,因為隨著項目越來越大,難免會遇到構(gòu)建速度越來越慢的問題,這個時候如何提高構(gòu)建速度就是我們需要考慮的問題了
這個適合于有一定android studio/gradle 構(gòu)建基礎(chǔ)的人觀看
其他解決方案
網(wǎng)上普遍有一些大家copy來copy去的答案,比如什么offline,也就是離線模式
開啟守護進程等方案
還有修改jvm的內(nèi)存大小
這些方案或多或少都看到過,但是修改這些對于我的項目沒有太多幫助
開發(fā)環(huán)境
android studio 2.3.3
mac
kotlin+java
這里就要說下我的項目研發(fā)過程
最初只有一個library,一個app,兩個module
mylibrary:
library是一個基礎(chǔ)項目,其中基本都是一些單類/utils的幫助工具,也是我多年開發(fā)的積累,或者是二次封裝的http請求庫
但是,因為業(yè)務(wù)發(fā)展,多了一個新的app,那我就將原來的app項目拆開
多了一個base的module,用于存放我的業(yè)務(wù)邏輯相關(guān)的基礎(chǔ)類庫
比如我封裝了自己的BaseApplication,這個Application中有我項目中需要初始化的數(shù)據(jù),比如數(shù)據(jù)數(shù)據(jù)統(tǒng)計SDK,crash上報SDK,初始化一些Service,比如更新應(yīng)用的Service,藍牙連接模塊的Service,都是所有項目都要用到的
另外還有BaseActivity,BaseFragment,BaseAdapter,網(wǎng)絡(luò)訪問的共有參數(shù)的封裝,數(shù)據(jù)傳輸加密方案的封裝
原app拆出來,稱為app1,新app也是一個module,稱為app2,一共是4個module了
后來我這里有業(yè)務(wù)需要,要接入二維碼掃碼,因為二維碼掃碼大家都是用的Zxing封裝庫,所以我也從網(wǎng)上找了一個,這個庫比較靠譜,有橫向/縱向/zxinglibrary的基礎(chǔ)庫,也就是3個庫,并且讓base依賴這個zxing項目,
在最初,我只有2個module,中期開始,也只有4個,勉強可以接受
現(xiàn)在:我有7個module了,而且后續(xù)又要開新的app開發(fā)項目,那么我就有8個module,并且項目間的依賴是
mylibrary-base-app1
zxinglibrary-pzxing-base-app1
也就是說我這里app項目的構(gòu)建有5個module參與,并且每次初次構(gòu)建時間超過3分鐘,這個時候我就有一個念頭,我要將不常用的模塊或者項目做成aar包,以縮減我的構(gòu)筑時間
制作aar包
這個我相信很多人都會,也很簡單,比如你運行了app1,然后library/base,中的build/output中都會生成結(jié)尾為aar的包,一個是debug的一個是release的,這樣的情況下,我們就可以引用這個aar包作為依賴
我這里因為base有可能今后還會頻繁修改,所以暫時將zxinglibrary,pzxing,mylibrary
引用過程
repositories {
mavenCentral()
flatDir {
dirs '../base/libs'
}
}
dependencies{
...
compile(name:'mylibrary-release',ext:'aar')
compile(name: 'portraitzxing-release', ext: 'aar')
compile(name: 'zxinglibrary-release', ext: 'aar')
}
報錯
這個是在base中的引用,sync一下,發(fā)現(xiàn)base中沒有問題,但是app中會報找不到引用,這個是因為aar只會將本module的相關(guān)資源/classes放到里面來,而不會關(guān)聯(lián)引用
舉個栗子
比如你的base依賴了mylibrary工程,而mylibrary工程中引用了v7包的東西,而你在原來使用compile project應(yīng)用的時候,你的base不需要引用v7包,也可以直接調(diào)用到v7的資源,因為你的mylibrary會將引用傳遞過來,而你使用mylibrary的aar包作為依賴的時候就不會這樣了,你如果需要使用v7的資源,你需要自己依賴 compile "com.android.support:appcompat-v7:$androidSupportVersion";
同理,這里雖然base引用了aar,但是你的app是無法直接調(diào)用aar的
這樣我們就需要在app的build.gradle中同樣引用這幾個aar了
在project根目錄中創(chuàng)建一個allproject.gradle
這個gradle的目的是將一些共有的引用/配置放到這里來,后面只需要引用到這個gradle,就可以直接調(diào)用相關(guān)的配置,而不用
allproject.gradle
import java.text.SimpleDateFormat
apply plugin: 'com.android.application'
repositories {
mavenCentral()
flatDir {
dirs '../base/libs'
}
}
dependencies {
compile(name: 'mylibrary-release', ext: 'aar')
compile(name: 'portraitzxing-release', ext: 'aar')
compile(name: 'zxinglibrary-release', ext: 'aar')
}
android {
signingConfigs {
config {
def dir = rootDir
storeFile file("${dir}/abc.jks")
storePassword "123341"
keyAlias "abc"
keyPassword "123341"
v2SigningEnabled false
}
}
compileSdkVersion compile_version
buildToolsVersion build_tools_version
//日期
SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd")
def dString = df.format(System.currentTimeMillis())
def service = "B"
def device = "M"
def os = "A"
def date = dString //第四至十一位:日期;
def index = "01" //第12到13位:流水號
def cate = "B" //14位:類型 B代表beta版,V代表正式版;
def ver
def betaVer;
def releaseVer;
buildTypes {
dev {
//開發(fā)版
minifyEnabled false
cate = "D"
ver = service + device + os + date + index
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'app/proguard-rules.pro'
buildConfigField("String", "VER", '"' + ver + cate + '"')
def type = getHttpType()
buildConfigField("String", "type", '"' + type + '"')
buildConfigField("String", "type", '"test"')
buildConfigField("int", "cate", '1')
buildConfigField("boolean", "Dev", "true")
betaVer = ver;
signingConfig signingConfigs.config
debuggable true
}
debug {
//debug版本
minifyEnabled false
debuggable true
cate = "B"
ver = service + device + os + date + index
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'app/proguard-rules.pro'
buildConfigField("String", "VER", '"' + ver + cate + '"')
buildConfigField("boolean", "Dev", "false")
buildConfigField("String", "type", '"test"')
// buildConfigField("String", "type", '"www"')
buildConfigField("int", "cate", '2')
buildConfigField("boolean", "Dev", "false")
betaVer = ver;
signingConfig signingConfigs.config
}
release {
//正式版
// minifyEnabled false
// debuggable true
minifyEnabled true
debuggable false
cate = "V"
ver = service + device + os + date + index
proguardFiles 'proguard-rules.pro'
buildConfigField("String", "VER", '"' + ver + cate + '"')
buildConfigField("boolean", "Dev", "false")
buildConfigField("String", "type", '"www"')
buildConfigField("int", "cate", '0')
buildConfigField("boolean", "Dev", "false")
releaseVer = ver;
signingConfig signingConfigs.config
}
}
productFlavors {
mysite {
manifestPlaceholders = [CHANNEL_VALUE: "mysite"]
}
}
applicationVariants.all { variant ->
variant.outputs.each { output ->
def buildType = variant.buildType
def type;
switch (buildType.name) {
case "release":
type = "V"
break
case "debug":
type = "B"
break
default:
type = "D"
}
println("buildType:" + buildType.name)
def fileName = "app${lastName(applicationId)}_${variant.productFlavors[0].name}_${ver}${type}.apk"
println("fileName = $fileName")
output.outputFile = new File(
output.outputFile.parent,
output.outputFile.name.replace(output.outputFile.name, fileName))
}
}
}
static String lastName(String applicationId) {
def split = applicationId.split("\\.")
return split[split.size() - 1]
}
app的build.gradle
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply from: '../allproject.gradle'
android {
defaultConfig {
defaultConfig {
applicationId "com.kikt.application"
minSdkVersion min_version
targetSdkVersion target_version
versionCode 19
versionName "1.1.9"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
}
}
...
這樣,每個項目中只需要apply from: '../allproject.gradle' 引用到這個gradle,就可以使用共有的構(gòu)建方案,引用同一個aar,根據(jù)不同的包名簽名輸出包的文件名不同
結(jié)果
原本的sync時間,3:00左右,現(xiàn)在gradle修改后的sync時間縮短到0:40~1:20,初次構(gòu)建時間由3分鐘縮短到1分20秒,instant run的時間由1分30秒縮短到40秒左右
后記
修改的過程趟了一些坑