当前位置:   article > 正文

Gradle多渠道打包(动态设定App名称,应用图标,替换常量,更改包名,变更渠道)_gradler 设置打包名称为变种名称

gradler 设置打包名称为变种名称

先放一个完整的 多渠道/多环境 打包的配置,然后再来讲解。

实现了:

  1. 不同环境,不同包名;
  2. 不同环境,修改不同的 string.xml 资源文件;
  3. 不同环境,修改指定的常量;
  4. 不同环境,修改 AndroidManifest.xml 里渠道变量;
  5. 不同环境,引用不同的 module。

先放一个完整的配置,可以参考:

  1. apply plugin: 'com.android.application'
  2. android {
  3. compileSdkVersion 22
  4. buildToolsVersion '22.0.1'
  5. // 签名文件
  6. signingConfigs {
  7. config {
  8. keyAlias 'lyl'
  9. keyPassword '123456'
  10. storeFile file('../lyl.jks')
  11. storePassword '123456'
  12. }
  13. }
  14. // 默认配置
  15. defaultConfig {
  16. //applicationId "com.lyl.app"
  17. minSdkVersion 16
  18. targetSdkVersion 22
  19. versionCode 1
  20. versionName "1.0.0"
  21. signingConfig signingConfigs.config
  22. multiDexEnabled true
  23. // gradle 3.0.0 以上需要有这个
  24. // flavorDimensions "app"
  25. }
  26. // 多渠道/多环境 的不同配置
  27. productFlavors {
  28. dev {
  29. // gradle 3.0.0 以上需要有这个
  30. // dimension "app"
  31. // 每个环境包名不同
  32. applicationId "com.lyl.dev"
  33. // 动态添加 string.xml 字段;
  34. // 注意,这里是添加,在 string.xml 不能有这个字段,会重名!!!
  35. resValue "string", "app_name", "dev_myapp"
  36. resValue "bool", "isrRank", 'false'
  37. // 动态修改 常量 字段
  38. buildConfigField "String", "ENVIRONMENT", '"dev"'
  39. // 修改 AndroidManifest.xml 里渠道变量
  40. manifestPlaceholders = [UMENG_CHANNEL_VALUE: "dev"]
  41. }
  42. stage {
  43. // gradle 3.0.0 以上需要有这个
  44. // dimension "app"
  45. applicationId "com.lyl.stage"
  46. resValue "string", "app_name", "stage_myapp"
  47. resValue "bool", "isrRank", 'true'
  48. buildConfigField "String", "ENVIRONMENT", '"stage"'
  49. manifestPlaceholders = [UMENG_CHANNEL_VALUE: "stage"]
  50. }
  51. prod {
  52. // gradle 3.0.0 以上需要有这个
  53. // dimension "app"
  54. applicationId "com.lyl.prod"
  55. resValue "string", "app_name", "myapp"
  56. resValue "bool", "isrRank", 'true'
  57. buildConfigField "String", "ENVIRONMENT", '"prod"'
  58. manifestPlaceholders = [UMENG_CHANNEL_VALUE: "prod"]
  59. }
  60. }
  61. dexOptions {
  62. incremental true
  63. // javaMaxHeapSize "4g"
  64. }
  65. //移除lint检测的error
  66. lintOptions {
  67. abortOnError false
  68. }
  69. def releaseTime() {
  70. return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC"))
  71. }
  72. buildTypes {
  73. debug {
  74. signingConfig signingConfigs.config
  75. }
  76. release {
  77. buildConfigField("boolean", "LOG_DEBUG", "false")
  78. minifyEnabled false
  79. zipAlignEnabled true
  80. //移除无用的resource文件
  81. shrinkResources true
  82. proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
  83. signingConfig signingConfigs.config
  84. // 批量打包(gradle 3.0.0 以下)
  85. applicationVariants.all { variant ->
  86. variant.outputs.each { output ->
  87. def outputFile = output.outputFile
  88. if (outputFile != null && outputFile.name.endsWith('.apk')) {
  89. //输出apk名称为:渠道名_版本名_时间.apk
  90. def fileName = "${variant.productFlavors[0].name}_v${defaultConfig.versionName}_${releaseTime()}.apk"
  91. output.outputFile = new File(outputFile.parent, fileName)
  92. }
  93. }
  94. }
  95. // 批量打包(gradle 3.0.0 以上)
  96. // android.applicationVariants.all { variant ->
  97. // variant.outputs.all {
  98. // outputFileName = // "${variant.productFlavors[0].name}_v${defaultConfig.versionName}_${releaseTime()}.apk"
  99. // }
  100. }
  101. }
  102. }
  103. }
  104. repositories {
  105. mavenCentral()
  106. }
  107. dependencies {
  108. compile 'com.facebook.android:facebook-android-sdk:4.0.0'
  109. compile project(':qrscan')
  110. compile 'com.android.support:appcompat-v7:22.0.0'
  111. compile 'com.google.code.gson:gson:2.3'
  112. compile files('libs/android-async-http-1.4.6.jar')
  113. compile 'com.google.android.gms:play-services:7.5.0'
  114. compile 'com.android.support:support-annotations:22.1.1'
  115. compile 'com.github.bumptech.glide:glide:3.7.0'
  116. compile 'de.hdodenhof:circleimageview:2.1.0'
  117. }

接下来我们来详细看看修改特定的字段。

不同环境的设置基本都是在 productFlavors 里设置的,
而且在里面你想添加多少个环境都可以。

1. 不同环境,不同包名;

  1. productFlavors {
  2. dev {
  3. applicationId "com.lyl.dev"
  4. }
  5. stage {
  6. applicationId "com.lyl.stage"
  7. }
  8. prod {
  9. applicationId "com.lyl.prod"
  10. }
  11. }

这里注意,在 defaultConfig 中,大家应该都是写了个默认的 applicationId 的。
经测试,productFlavors 设置的不同环境包名会覆盖 defaultConfig 里面的设置,
所以我们可以推测,它执行的顺序应该是先执行默认的,然后在执行分渠道的,如果冲突,会覆盖处理,这也很符合逻辑。

2. 不同环境,添加 string.xml 资源文件;

利用 resValue 来定义资源的值,顾名思义 res 底下的内容应该都可以创建,最后用 R.xxx.xxx 来引用。
如下就根据不同的类型,添加了不同的 app_name 字段,以及定义了 布尔值,可以通过 R.string.app_name 来引用。

注意,这里是添加,是在 string.xml 里面添加了一个字段app_name,所以在现有的 string.xml 中不能有这个字段,否则会报错!!!

  1. productFlavors {
  2. dev {
  3. resValue "string", "app_name", "dev_myapp"
  4. resValue "bool", "isrRank", 'false'
  5. }
  6. stage {
  7. resValue "string", "app_name", "stage_myapp"
  8. resValue "bool", "isrRank", 'true'
  9. }
  10. prod {
  11. resValue "string", "app_name", "myapp"
  12. resValue "bool", "isrRank", 'true'
  13. }
  14. }

通过以上我们大概可以推测出 color、dimen 也可以通过类似的方法添加。

3. 不同环境,动态修改指定的常量;

使用 BuildConfig 的变量。

①定义字段

当我们定义如下字段之后,编译后自动生成文件,在 app/build/source/BuildConfig/dev/com.lyl.dev/BuildConfig 目录,
打开这个文件,我们就能看到我们所定义的字段了。

  1. productFlavors {
  2. dev {
  3. buildConfigField "String", "ENVIRONMENT", '"dev"'
  4. }
  5. stage {
  6. buildConfigField "String", "ENVIRONMENT", '"stage"'
  7. }
  8. prod {
  9. buildConfigField "String", "ENVIRONMENT", '"prod"'
  10. }
  11. }

②引用字段

在我们自己的任意的类中,来直接通过 BuildConfig 就可以调用我们定义的字段。

  1. public class Constants {
  2. public static final String ENVIRONMENT = BuildConfig.ENVIRONMENT;
  3. }

注意: 这里有个小细节,看其中第三个参数,是先用了“'”,然后在用了“"”,这种语法在 Java 里可能比较陌生,但是在很多其他语言中,这种用法是很常见的。

它的意思是 "dev" 这个整体是属于一个字符串,至于为什么要这么写,你把单引号去掉,然后去 app/build/source/BuildConfig/dev/com.lyl.dev/BuildConfig 这个文件看一看就知道了。

4. 不同环境,修改 AndroidManifest.xml 里渠道变量

①在 AndroidManifest.xml 里添加渠道变量

  1. <application
  2. android:icon="${app_icon}"
  3. android:label="@string/app_name"
  4. android:theme="@style/AppTheme">
  5. ...
  6. <meta-data
  7. android:name="UMENG_CHANNEL"
  8. android:value="${ENVIRONMENT}" />
  9. ...
  10. </application>

②在 build.gradle 设置 productFlavors

  1. productFlavors {
  2. dev {
  3. manifestPlaceholders = [ENVIRONMENT: "dev",
  4. app_icon : "@drawable/icon_dev"]
  5. }
  6. stage {
  7. manifestPlaceholders = [ENVIRONMENT: "stage",
  8. app_icon : "@drawable/icon_stage"]
  9. }
  10. prod {
  11. manifestPlaceholders = [ENVIRONMENT: "prod",
  12. app_icon : "@drawable/icon_prod"]
  13. }
  14. }

这样我们可以在不同环境使用不同的 key 值。

5. 不同环境,引用不同的 module

这个就很强大了,根据不同的环境,引用对应的 module。
你可以替换大量的图片,string,color,vaule等等。

首先,要建立跟渠道对应的 module,然后再引用。
引用方式如下:

  1. dependencies {
  2. compile fileTree(dir: 'libs', include: ['*.jar'])
  3. // 引用本的项目
  4. devCompile project(':devModule')
  5. stageCompile project(':stageModule')
  6. prodCompile project(':prodModule')
  7. // 也可以分渠道引用网络的。因为这里都相同,所以地址也就都一样了
  8. devCompile 'com.roughike:bottom-bar:2.0.2'
  9. stageCompile 'com.roughike:bottom-bar:2.0.2'
  10. prodCompile 'com.roughike:bottom-bar:2.0.2'
  11. }

xxxCompile 代表 各个渠道的名称。
然后把需要分渠道的文件,放到不同的 module 里面,把主项目的文件删掉。
千万注意: 如果这样做了,每次需要引用的时候,在各个渠道的 module 里面都必须要放置文件哦,不然会找不到资源。
通过这种方式可以替换整套素材资源,具体如何使用还得看项目需求。

通过以上方式,我们基本可以 通过 gradle 动态设定应用标题,应用图标,替换常量,设置不同包名,更改渠道等等。


打包编译

最后,做完所有的配置之后,然后就是打包操作了。

打包某一个(日常编译)

因为 buildTypes 里面有两种,所以每个渠道都会有两种模式。

 

打包所有的,就是正常打包流程

如图所示:

 

打包完成之后,然后就可以在我们指定的目录下,看到我们所生成的apk包。


使用 local.properties 存放私密配置

以上就可以基本实现 gradle 的设置,但是如果我们要将我们的项目上传到 Github ,或者要将项目发送给别人。上面有些私密的东西就会被别人看到。比如:.jks 文件的密码。

在项目跟目录下,有个 local.properties 文件,我们可以使用它来存放一些私密的属性,然后在 gradle 中读取,而 local.properties 文件不需要上传。
local.properties 文件里设置如下:

  1. sdk.dir=D\:\\Android\\android-sdk
  2. gaodeKey=e348025dd034d1c347dd0345e34802
  3. keyPassword=123456

在 build.gradle 读取 local.properties 字段信息

  1. // 加载 local.properties 资源
  2. Properties properties = new Properties()
  3. InputStream inputStream = project.rootProject.file('local.properties').newDataInputStream() ;
  4. properties.load( inputStream )
  5. android {
  6. ...
  7. // 签名文件
  8. signingConfigs {
  9. config {
  10. keyAlias 'lyl'
  11. // 获取 local.properties 字段信息
  12. keyPassword properties.getProperty( 'keyPassword' )
  13. storeFile file('../lyl.jks')
  14. storePassword properties.getProperty( 'keyPassword' )
  15. }
  16. }
  17. ...
  18. }

这样就可以将自己想要隐藏的一些数据隐藏起来。


可能加快 Android Studio 编译的办法

1. 在根目录的 build.gradle 里加上如下代码:

  1. allprojects {
  2. // 加上这个
  3. tasks.withType(JavaCompile) {
  4. //使在一个单独的守护进程编译
  5. options.fork = true
  6. //增量编译
  7. options.incremental = true
  8. }
  9. repositories {
  10. jcenter()
  11. }
  12. }

2. 在 app 级别下 build.gradle 里 加上

  1. android {
  2. dexOptions {
  3. incremental true
  4. }
  5. }

最后放上一个多渠道的项目地址,可以参考:
https://github.com/Wing-Li/boon



作者:Wing_Li
链接:https://www.jianshu.com/p/533240d222d3
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

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

闽ICP备14008679号