菜鳥級別的程序媛,首次做多渠道打包,也是查了一些資料,希望可以幫到你們。
本文來自:http://www.itdecent.cn/u/7dcee8463e30
因項目需求,需要給定制客戶在原有基礎(chǔ)上出一個APP,只更換APP的icon和name。同時項目也有少量部分需要修改的地方,為了更好的迭代開發(fā),Gradle的多渠道打包就派上用場了。
先貼一份主Module的build.gradle文件參考
apply plugin: 'com.android.application'
//************************新增***************************
//獲取當(dāng)前的時間
def releaseTime() {
return new Date().format("HHmm")
}
//設(shè)置自增長版本號
def getVersionCode() {
def versionFile = file('version.properties')// 讀取第一步新建的文件
if (versionFile.canRead()) {// 判斷文件讀取異常
Properties versionProps = new Properties()
versionProps.load(new FileInputStream(versionFile))
def versionCode = versionProps['VERSION_CODE'].toInteger()// 讀取文件里面的版本號
def runTasks = gradle.startParameter.taskNames
if ('assembleRelease' in runTasks) {//僅在assembleRelease任務(wù)是增加版本號,其他渠道包在此分別配置
// 版本號自增之后再寫入文件(此處是關(guān)鍵,版本號自增+1)
versionProps['VERSION_CODE'] = (++versionCode).toString()
versionProps.store(versionFile.newWriter(), null)
}
return versionCode // 返回自增之后的版本號
} else {
throw new GradleException("Could not find version.properties!")
}
}
def getVersionName() {
def date = new Date()
def versionName = date.format('yyyyMMdd')
return versionName
}
def currentVersionCode = getVersionCode()
def currentVsionName = getVersionName()
android {
compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
// 取消掉系統(tǒng)對.9圖片的檢查
aaptOptions.cruncherEnabled = false
aaptOptions.useNewCruncher = false
lintOptions {
checkReleaseBuilds false
// Or, if you prefer, you can continue to check for errors in release builds,
// but continue the build even when errors are found:
abortOnError false
}
//需要添加下面選項,否則無法run app
dexOptions {
javaMaxHeapSize "4g"
// incremental true
jumboMode = true
preDexLibraries = false
}
defaultConfig {
applicationId "com.andorid.xxx.xxx"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode currentVersionCode
versionName currentVsionName
multiDexEnabled true
flavorDimensions "app"http://新增
javaCompileOptions { annotationProcessorOptions { includeCompileClasspath = true } }
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "Umeng"]
ndk {
//設(shè)置支持的SO庫架構(gòu)
abiFilters "armeabi", "armeabi-v7a", "x86"
}
vectorDrawables.useSupportLibrary = true
javaCompileOptions {
annotationProcessorOptions {
includeCompileClasspath = true
}
}
}
buildTypes {
debug {
minifyEnabled false
zipAlignEnabled false
shrinkResources false
debuggable true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
release {
minifyEnabled true
zipAlignEnabled false
shrinkResources false
debuggable false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
//*************************新增start**********************************
productFlavors {
//********(默認(rèn)渠道)******
pro {
manifestPlaceholders = [
UMENG_CHANNEL_VALUE: "pro",
app_icon : "@drawable/pro_icon",
app_name : "@string/pro_app_name",
]
}
//********定制的XXX(applicationId不一樣)******
dev {
applicationId "com.andorid.xxx.xxx"
manifestPlaceholders = [
UMENG_CHANNEL_VALUE: "dev",
app_icon : "@drawable/dev_logo",
app_name : "@string/dev_app_name",
]
}
}
android.applicationVariants.all {
variant ->
variant.outputs.all {
output ->
def outputFile = output.outputFile
def fileName
if (outputFile != null && outputFile.name.endsWith('.apk')) {
if (variant.buildType.name.equals('release')) {
fileName = "${variant.productFlavors[0].name}_release_${defaultConfig.versionName}_${releaseTime()}.apk"
} else if (variant.buildType.name.equals('debug')) {
fileName = "${variant.productFlavors[0].name}_debug_${defaultConfig.versionName}_${releaseTime()}.apk"
}
outputFileName = fileName
}
}
}
//*************************新增End**********************************
sourceSets {
main {
jniLibs.srcDirs = ['src/main/jniLibs']
}
}
//引人aar
repositories {
flatDir {
dirs 'libs'
}
maven { url "https://jitpack.io" }
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
dataBinding {
enabled = true
}
dependencies {
compileOnly fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'com.android.support:design:28.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation 'com.google.code.gson:gson:2.8.2'
implementation files('libs/glide-3.7.0.jar')
implementation files('libs/jaxen-1.1.1.jar')
implementation 'org.greenrobot:eventbus:3.0.0'
compile 'com.orhanobut:logger:2.1.1'
compile 'com.zhy:okhttputils:2.6.2'
compile 'com.android.support:multidex:1.0.1'
compile 'com.squareup.okhttp3:okhttp:3.3.0'
compile 'com.umeng.sdk:debug:1.0.0'
implementation 'me.jessyan:autosize:1.1.2'
}
}
下面請跟著我的步驟來
由于andorid對每個app唯一標(biāo)識是用applicationId來標(biāo)識的,所以每個渠道的包根據(jù)applicationId來區(qū)分。
productFlavors {
//********(默認(rèn)渠道)******
pro {
manifestPlaceholders = [
UMENG_CHANNEL_VALUE: "pro",
app_icon : "@drawable/pro_icon",
app_name : "@string/pro_app_name",
]
}
//********定制的xxx(applicationId不一樣)******
dev {
applicationId "com.android.xxx.xxx"
manifestPlaceholders = [
UMENG_CHANNEL_VALUE: "dev",
app_icon : "@drawable/dev_logo",
app_name : "@string/dev_app_name",
]
}
}
記得在AndroidManifest文件的application節(jié)點中引用app的icon和name
meta-data節(jié)點一定不能少的哦別忘記了。這里的配置是動態(tài)改變icon和name
<application···
android:icon="${app_icon}"
android:label="${app_name}"
<meta-data
android:name="CHANNEL_ID"
android:value="${UMENG_CHANNEL_VALUE}" />
接下就是打包app里,我這里做了一個判斷,給apk包名命名是debug的還是release的
android.applicationVariants.all {
variant ->
variant.outputs.all {
output ->
def outputFile = output.outputFile
def fileName
if (outputFile != null && outputFile.name.endsWith('.apk')) {
if (variant.buildType.name.equals('release')) {
fileName = "${variant.productFlavors[0].name}_release_${defaultConfig.versionName}_${releaseTime()}.apk"
} else if (variant.buildType.name.equals('debug')) {
fileName = "${variant.productFlavors[0].name}_debug_${defaultConfig.versionName}_${releaseTime()}.apk"
}
outputFileName = fileName
}
}
}
接下來就讓我們來看一下打包的效果吧!
image.png
另外如果程序里面某些配置需要根據(jù)不同的渠道配置,可以獲取applicationId,也就是包名。
例如:
image.png

