当前位置:   article > 正文

Android多渠道打包配置_设置多个buildtypes

设置多个buildtypes

Android多渠道打包配置

之前为了在同一台手机能同时安装测试包和生产包,采用配置buildType的方式来实现,相比于flavor,感觉是挺轻量又恰到好处的配置,具体见通过配置applicationId来实现测试包和生产包安装在同一台手机上。最近因为业务需要,需要多个渠道的包了,这就必须要用到flavor这个大杀器了。一路配置下来,感觉还挺顺,下面就具体记录一下。

目标

先说一下需求,增加一个渠道

  1. 功能代码几乎完全相同,个别接口要根据渠道传参
  2. logo要按渠道配置
  3. 应用程序的名子也要不同
  4. 部分页面的标识性图片要按渠道配置

大概就是这么些东西需要根据渠道来配置的。不过还有一些潜在的东西也需要按渠道来配置,如:

  • applicationId,肯定是要不同的
  • 签名肯定是区分的
  • 百度地图的key也必须要根据渠道配置的,以及其它类似的三方鉴权相关配置
  • 自动升级时安装app所需要的fileProviderAuthority也要区分

由于我还保留着degbug与release包使用不同的applicationId,实际上两个渠道共4个包都是不同id的,某些参数除了要根据渠道区分还要再根据buildType做相应的配置。

实施

一、先把flavor配置起来,在app的build.gradle文件中的 android 代码块中添加

// 定义flavor的dimension,至少要有一个dimension,名字随便取,这个必须要的,不然会报错
flavorDimensions "version"

// 渠道包定义,默认定义的名称就是渠道名称
productFlavors {
    // google渠道
    google {
        applicationId = "com.my.google"
    }
    // twitter渠道
    twitter {
        applicationId = "com.my.twitter"
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

这里配置了两个渠道,并指定了它们各自的applicationId,值得注意的是必须要先设置flavorDimensions,值可以随便取。

二、配置签名

//配置签名
signingConfigs {
    google {
        storeFile file("D:/docs/keyStore/googleKeyStore.jks")
        storePassword "111111"
        keyAlias "key0"
        keyPassword "222222"
    }
    twitter {
        storeFile file("D:/docs/keyStore/twitterKeyStore.jks")
        storePassword "333333"
        keyAlias "key1"
        keyPassword "444444"
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

storeFile是KeyStore.jks文件所在的目录,这里配置的所有内容都是创建jks的时候自己填的。

jks的创建

as菜单 Build–>Generate Signed Bundle/APK…->选中APK–>Next–>Create new…

在打开的填写文件路径、密码等内容,一路next就行了

配置好之后,在flavor块中加上对签名的引用,如下

productFlavors {
    // google渠道
    google {
        applicationId = "com.my.google"
        signingConfig signingConfigs.google
    }
    // twitter渠道
    twitter {
        applicationId = "com.my.twitter"
        signingConfig signingConfigs.twitter
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 注意一点,signingConfigs{…}代码块要放在引用它的代码之前,否则会找不到引用的签名

三、 配置只需要区分渠道而不需要区分buildType的参数,如:页面中的图片,接口参数等

这些参数都可以用buildConfigField方法来设置,这个方法将在BuildConfig类中添加一个字段,它接受三个参数,第一个是数据类型,第二个是字段名,第三个是字段值,如:

buildConfigField "Integer", "LOGIN_ICON", "R.drawable.login_icon_google"
buildConfigField "String", "LOGIN_TEXT", "请输入google账号"
  • 1
  • 2

在java代码中直接用 BuildConfig.LOGIN_ICONBuildConfig.LOGIN_TEXT 来引用对应的图片或文字,非常方便。将这个代码写在flavor块内,如下:

productFlavors {
    // google渠道
    google {
        applicationId = "com.my.google"
        signingConfig signingConfigs.google
		buildConfigField "Integer", "LOGIN_ICON", "R.drawable.login_icon_google"
		buildConfigField "String", "LOGIN_TEXT", "\"请输入google账号\""
    }
    // twitter渠道
    twitter {
        applicationId = "com.my.twitter"
        signingConfig signingConfigs.twitter
		buildConfigField "Integer", "LOGIN_ICON", "R.drawable.login_icon_twitter"
		buildConfigField "String", "LOGIN_TEXT", "\"请输入twitter账号\""
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

四、配置buildType的内容,有部分内容还要区分flavor,如:appName,百度地图key等

buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
			// 配置生产环境url
            buildConfigField "String", "BASE_URL", "\"https://a.b.c.release.com\""
            // 要区分渠道的内容
            if (mFlavor == "google") {
                // google渠道生产版百度地图key
                manifestPlaceholders = [baiduMapKey          : "11111111111",
                                        fileProviderAuthority: "aaaaaaaa",
                                        logo                 : "R.drawable.logo_google_release"
                ]

                resValue 'string', 'app_name', "我的应用google版"
                resValue 'string', 'authority', "aaaaaaaa"

            } else {
                // twitter渠道生产版百度地图key
                manifestPlaceholders = [baiduMapKey          : "22222222",
                                        fileProviderAuthority: "bbbbbbbbb",
                                        logo                 : "R.drawable.logo_twitter_release",
                ]
                resValue 'string', 'app_name', "我的应用twitter版"
                resValue 'string', 'authority', "bbbbbbbbb"
            }
        }
        debug {
			// debug包的applicationId在生产包的后面加上后缀".abc"
            applicationIdSuffix ".abc"
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            // 配置测试环境url
            buildConfigField "String", "BASE_URL", "\"https://a.b.c.release.com\""
            // 要区分渠道的内容
            if (mFlavor == "google") {
                // google渠道测试版百度地图key
                manifestPlaceholders = [baiduMapKey          : "88888888",
                                        fileProviderAuthority: "mmmmmmmmm",
                                        logo                 : "R.drawable.logo_google_debug"
                ]

                resValue 'string', 'app_name', "我的应用google版_测试包"
                resValue 'string', 'authority', "mmmmmmmmm"

            } else {
                // twitter渠道测试版百度地图key
                manifestPlaceholders = [baiduMapKey          : "99999999",
                                        fileProviderAuthority: "nnnnnnnnn",
                                        logo                 : "R.drawable.logo_twitter_debug"
                ]
                resValue 'string', 'app_name', "我的应用twitter版_测试包"
                resValue 'string', 'authority', "nnnnnnnnn"
            }
        }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56

这里用到了另外两种配置参数的方法,一是manifestPlaceholders,二是resValue。
manifestPlaceholders 可以在 AndroidManifest.xml 中替换参数的值,它接受一个 Map<String, Object> 类型的参数,如以下配置

manifestPlaceholders = [baiduMapKey          : "99999999",
                        logo                 : "R.drawable.logo_twitter_debug"
                ]
  • 1
  • 2
  • 3

在 AndroidManifest.xml 文件中用以下方式来取得配置的值:

<!-- 百度地图开发者key -->
<meta-data
    android:name="com.baidu.lbsapi.API_KEY"
    android:value="${baiduMapKey}" />

android:icon="${logo}"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

这样,不同渠道取出来的 baiduMapKey 值就不一样了,达到了动态配置的目的

resValue 相当于在 res/values 文件夹下的某个资源文件中增加一个资源,比如在 res/values/strings 中增加一个字符串

resValue 'string', 'app_name', "我的应用twitter版_测试包"
  • 1

在 xml 文件中就可以引用这个字符串了

android:label="@string/app_name"
  • 1

这种方式要注意一点:如果原先 strings.xml 文件中已经定义了一个 app_name 的字符串,必须要将这个定义去掉,否则会报资源重复的错误。

还有一点值得注意的是:在 buildType 代码块中怎么判断 flavor ,我借鉴了网上的一种方法,是根据taskName来判断当前编译的代码是属于哪个渠道,不知道有没有更好方式来判断了。

def getFlavor() {
    def runTasks = gradle.startParameter.taskNames
    def gR = ':app:assembleGoogleRelease'
    def gD = ':app:assembleGoogleDebug'
    def tR = ':app:assembleTwitterRelease'
    def tD = ':app:assembleTwitterDebug'
    if (gR in runTasks || gD in runTasks) {
        return "google"
    }
    if (tR in runTasks || tD in runTasks) {
        return "twitter"
    }
    return ""
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

这样,整个配置就完成了,下面把完整的 app下的build.gradle文件中跟渠道配置相关的代码贴出来

android {
	// 获取渠道名
    def mFlavor = getFlavor()

    compileSdkVersion 28
    defaultConfig {
        minSdkVersion 15
        targetSdkVersion 26
        // 版本号
        versionCode 123
        // 版本名
        versionName 1.2.3
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        multiDexEnabled true
    }

	//配置签名
    signingConfigs {
        google {
            storeFile file("D:/docs/keyStore/googleKeyStore.jks")
            storePassword "111111"
            keyAlias "key0"
            keyPassword "222222"
        }
        twitter {
            storeFile file("D:/docs/keyStore/twitterKeyStore.jks")
            storePassword "333333"
            keyAlias "key1"
            keyPassword "444444"
        }
    }

	buildTypes {
	    release {
	        minifyEnabled true
	        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
		 	// 配置生产环境url
	        buildConfigField "String", "BASE_URL", "\"https://a.b.c.release.com\""
	        // 要区分渠道的内容
	        if (mFlavor == "google") {
	            // google渠道生产版百度地图key
	            manifestPlaceholders = [baiduMapKey          : "11111111111",
	                                    fileProviderAuthority: "aaaaaaaa",
	                                    logo                 : "R.drawable.logo_google_release"
	            ]
	    
	            resValue 'string', 'app_name', "我的应用google版"
	            resValue 'string', 'authority', "aaaaaaaa"
	    
	        } else {
	            // twitter渠道生产版百度地图key
	            manifestPlaceholders = [baiduMapKey          : "22222222",
	                                    fileProviderAuthority: "bbbbbbbbb",
	                                    logo                 : "R.drawable.logo_twitter_release",
	            ]
	            resValue 'string', 'app_name', "我的应用twitter版"
	            resValue 'string', 'authority', "bbbbbbbbb"
	        }
	    }
	    debug {
		 	// debug包的applicationId在生产包的后面加上后缀".abc"
	        applicationIdSuffix ".abc"
	        minifyEnabled false
	        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
	        // 配置测试环境url
	        buildConfigField "String", "BASE_URL", "\"https://a.b.c.release.com\""
	        // 要区分渠道的内容
	        if (mFlavor == "google") {
	            // google渠道测试版百度地图key
	            manifestPlaceholders = [baiduMapKey          : "88888888",
	                                    fileProviderAuthority: "mmmmmmmmm",
	                                    logo                 : "R.drawable.logo_google_debug"
	            ]
	    
	            resValue 'string', 'app_name', "我的应用google版_测试包"
	            resValue 'string', 'authority', "mmmmmmmmm"
	    
	        } else {
	            // twitter渠道测试版百度地图key
	            manifestPlaceholders = [baiduMapKey          : "99999999",
	                                    fileProviderAuthority: "nnnnnnnnn",
	                                    logo                 : "R.drawable.logo_twitter_debug"
	            ]
	            resValue 'string', 'app_name', "我的应用twitter版_测试包"
	            resValue 'string', 'authority', "nnnnnnnnn"
	        }
	    }
    }

    // 定义flavor的dimension,至少要有一个dimension,名字随便取,这个必须要的,不然会报错
    flavorDimensions "version"

	productFlavors {
        // google渠道
        google {
            applicationId = "com.my.google"
            signingConfig signingConfigs.google
			buildConfigField "Integer", "LOGIN_ICON", "R.drawable.login_icon_google"
    		buildConfigField "String", "LOGIN_TEXT", "\"请输入google账号\""
        }
        // twitter渠道
        twitter {
            applicationId = "com.my.twitter"
            signingConfig signingConfigs.twitter
			buildConfigField "Integer", "LOGIN_ICON", "R.drawable.login_icon_twitter"
    		buildConfigField "String", "LOGIN_TEXT", "\"请输入twitter账号\""
        }
    }
}

def getFlavor() {
    def runTasks = gradle.startParameter.taskNames
    def gR = ':app:assembleGoogleRelease'
    def gD = ':app:assembleGoogleDebug'
    def tR = ':app:assembleTwitterRelease'
    def tD = ':app:assembleTwitterDebug'
    if (gR in runTasks || gD in runTasks) {
        return "google"
    }
    if (tR in runTasks || tD in runTasks) {
        return "twitter"
    }
    return ""
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124




由于水平有限,如果文中存在错误之处,请大家批评指正,欢迎大家一起来分享、探讨!

博客:http://blog.csdn.net/MingHuang2017

GitHub:https://github.com/MingHuang1024

Email: MingHuang1024@foxmail.com

微信:724360018

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/252972
推荐阅读
相关标签
  

闽ICP备14008679号