菜鸟级别的程序媛,首次做多渠道打包,也是查了一些资料,希望可以帮到你们。
本文来自:https://www.jianshu.com/u/7dcee8463e30
因项目需求,需要给定制客户在原有基础上出一个APP,只更换APP的icon和name。同时项目也有少量部分需要修改的地方,为了更好的迭代开发,Gradle的多渠道打包就派上用场了。
先贴一份主Module的build.gradle文件参考
apply plugin: 'com.android.application'
//************************新增***************************
//获取当前的时间
def releaseTime() {
return new Date().format("HHmm")
}
//设置自增长版本号
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任务是增加版本号,其他渠道包在此分别配置
// 版本号自增之后再写入文件(此处是关键,版本号自增+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
// 取消掉系统对.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"//新增
javaCompileOptions { annotationProcessorOptions { includeCompileClasspath = true } }
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "Umeng"]
ndk {
//设置支持的SO库架构
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 {
//********(默认渠道)******
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唯一标识是用applicationId来标识的,所以每个渠道的包根据applicationId来区分。
productFlavors {
//********(默认渠道)******
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节点中引用app的icon和name
meta-data节点一定不能少的哦别忘记了。这里的配置是动态改变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
另外如果程序里面某些配置需要根据不同的渠道配置,可以获取applicationId,也就是包名。
例如: image.png
网友评论