暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

使用gradle的productFlavors实现Android项目多渠道打包

WTech 2018-04-29
2133

      productFlavors是在gradle中配置多渠道的打包的工具。使用productFlavors区分不同的产品,定义不同的逻辑,使构建部分有差异的Android项目更加方便。

       什么是渠道包呢?渠道包就是为不同的应用市场打的apk包。一般的做法是在发布的apk包的清单文件中的某个meta-data标签下,配置相应value,这个标签的作用就是用来区分是哪个市场的,比如你发布到360.这个值就是你就可以配置成360,豌豆荚就可以配置成wandoujia,这么配置的作用是用来做统计用的,比如使用友盟统计,它就可以统计用户从哪个平台下载了你们的app,从而更好的掌握用户的操作习惯。所以,如果app没有统计功能的需求,你只需要打一个同样的包,直接发布到各个平台即可,根本不用关心什么渠道。

      设置productFlavors的步骤如下:

1.创建不同的产品

app:
级别下的build.gradle文件中,如下图1,加入productFlavors,并创建不同的产品,并为不同的产品分配专有属性。如:productFlavors
下创建产品product
temp

图1

android {

...

flavorDimensions "prod"

   
productFlavors {
//新建产品product
       
product {
//程序包名,可以编译出不包名的apk
           
applicationId "study.ung.differentsource.product"
           
//不同渠道号
           
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "360"]
//versionName
           
versionName "1.0.0"
           
//versionCode
           
versionCode 1

           
dimension "prod"

       
}

//新建产品temp
       
temp {
//程序包名,可以编译出不包名的apk
           
applicationId "study.ung.differentsource.temp"
           
//不同渠道号
           
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "wandoujia"]
//versionName
           
versionName "2.1.1"
           
//versionCode
           
versionCode 2

           
dimension "prod"
       
}


}
}


注意:所有的flavors都必须同属于某一个范围,所以要在productFlavors外面定义:

flavorDimensions "自定义名称" ,如flavorDimensions "prod",

然后在每个flavors中都加入:dimension "prod"让其属于prod这个范围。

这是插件3.0.0的一个新的依赖机制,它会在使用库时自动匹配变体。


还可以通过以下方法指定渠道:

productFlavors {

wandoujia {}
baidu {}
c360 {}
uc {}
productFlavors.all { flavor ->
flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
}

...
}

 


2.设置不同的代码引用

切换到project视窗,先在src目录下,创建对应的文件夹,如本文的例子,就是要创建product和temp文件夹,然后在它们里面创建与main文件夹下一模一样的目录结构。对于资源文件夹res,则建立product/res、temp/res。如下图:



3.在app:级别下的build.gradle文件中设置不同产品的sourceSets,即指定不同产品的源码文件所在的路径,如下所示:


android {

   ...
     

sourceSets {
//不同产品不同的文件
       product {
java.srcDirs = ['src/product/java']
}
temp {
java.srcDirs = ['src/temp/java']
}
}


flavorDimensions "prod"

   productFlavors {

...

}
}


4.在app:级别下的build.gradle文件中设置不同产品引入的不同的依赖包

旧Gradle版本的方式:产品名Compile 'xxx.xxx.xx'

新Gradle版本的方式:产品名Implementation 'xxx.xxx.xx'

如果引入的就依赖包没有产品名作为前缀,则为main所用,即公共的。

apply plugin: 'com.android.application'

android {
...
}

dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support:appcompat-v7:27.1.1'
   ...
   
productImplementation 'com.android.support:design:27.1.1'

   tempImplementation 'com.alibaba:fastjson:1.2.47'
}


5.最后,在Android Studio左下角的Build Variants菜单中可以看到如下界面: 

如果还像下面那样指定了其他渠道:

productFlavors {

wandoujia {}
baidu {}
c360 {}
uc {}
productFlavors.all { flavor ->
flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
}

...
}

还可以见到其他渠道版本,如下所示:

我们在run一个项目时,在Build Variants视窗里选相应的Build Variant,它就会将相应的差异部分和main合并在一起编译,最终运行成一个项目。

注意:指定了渠道,就要像product、temp那样定义出各个渠道的产品,否则在打包时列表中会没有相应的渠道版本可以选择。

       总结:我们把相同部分放在main下,有差异的部分就放productFlavors声明的相应的项目里,运行时,根据Build Variant的选择,将相应项目的差异部分合并到main里来一起编译。

       应用举例:在实际中,我们有生产环境、测试环境、灰度环境,它们使用了不同的服务器、数据库,我们使用productFlavors创建一些产品并将这些服务器、数据库信息,存到这些产品的某个文件里,比如说在product/java/com.wong/product/AppConfig配置正式生产环境的信息,在temp/java/com.wong/product/AppConfig配置正式测试环境的信息。这样我们就随意切换环境了。


文章转载自WTech,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论