基础知识
首先我们要知道gradle中有一个功能叫做变体「productflavors」,这是来为APP设置不同的打包配置,以实现多渠道打包的一种方案。基本形式如下:
android { ... buildTypes { debug { ... } qa { ... } release { ... } } productFlavors { baidu{} _360{} yingyongbao{} }
这样的话最后打包的时候就可以生成9种包:
· baiduDebug· baiduQa· baiduRelease· _360Debug· _360Qa· _360Release· yingyongbaoDebug· yingyongbaoQa· yingyongbaoRelease
在Android Studio左下角可以找到并在每次build的时候选择不同种类的包
QQ截图20170814183444.png
注意名称不能用数字,所以我这里没有用360。
实现分渠道配置
配置java变量
在gradle中有一个功能叫「buildConfigField」,可以在系统的buildconfig中设置一个值。如下:
buildConfigField 'boolean', 'ISB', 'true'
这样就可以在app中使用boolean类型的变量BuildConfig.ISB=true
这里也可以建立一个string值,如下:buildConfigField 'String', 'val', '"content"'
在java代码中使用Build.val 可以使用这个量,值为content
QQ截图20170814183904.png
配置manifest变量
很多第三方sdk喜欢在manifest中配置appkey等,可以在gradle中使用:
manifestPlaceholders = [UMENG_CHANNEL: "0", UMENG_APPKEY : "123456789"]
然后在manifest中配置
就可以实现。
配置包名
在gradle中包名用applicationId
代表。还可以使用applicationIdSuffix
在后面加一个后缀。
applicationId "com.a.b"
使用
applicationIdSuffix ".c"
最终打包以后的包名就是com.a.b.c
。
配置版本号
是的,versionCode和versionName也可以自己配置,毕竟他们是一个变量~
实战
前面说了这么多可配置的项,其实我还有一点没有说,那就是这一切都是可以在productFlavors
和buildTypes
配置的!
日志开关
buildTypes { debug { buildConfigField 'boolean', 'PROXY', 'true' } qa { buildConfigField 'boolean', 'PROXY', 'true' } release { buildConfigField 'boolean', 'PROXY', 'false' }
在buildTypes
中配置,release
配置为false 其他为true。便于调试
api环境地址
一般情况下后端的api地址区别就在于域名,所以在debug
qa
release
可以使用不同的域名
buildTypes { debug { buildConfigField 'String', 'API_HOST', '"http://dev.example.com/"' } qa { buildConfigField 'String', 'API_HOST', '"http://qa.example.com/"' } release { buildConfigField 'String', 'API_HOST', '"https://example.com/v1/"' } }
不同的包名 版本号
这些都是可以使用自带的属性进行配置。在不同的buildTypes
中赋值不同即可。
productFlavors { baidu { applicationId "com.janus.baidu.advancedgradledemo" versionCode 1 versionName "1.0.0" } _360 { applicationId "com.janus.360.advancedgradledemo" versionCode 2 versionName "1.0.2" } yingyongbao { applicationId "com.janus.yingyongbao.advancedgradledemo" versionCode 3 versionName "1.0.3" } }
更高级的实战:不同的APP名称 图标 UI等
相信大家都遇到过这种情况,公司做出了一个统一框架,只有业务逻辑是不同的,其他的都一样。其中业务逻辑是随着OEM厂商而变化的,同时UI 图标 描述语等也是不同的。一般的情况下就只能分开成好几个项目了,不过在这里可以用一种方法实现。
如果有2个oem分别叫做oea oeb 我们可以使用productFlavors
做出2个flavor productFlavors { oea { } oeb { } }
APP名称
名称是在manifest
的application
节点下的label
属性设置。我们可以使用manifestPlaceholders
进行设置
manifest
中: 注意:动态替换label需要添加一行 tools:replace="android:label"
gradle
中: productFlavors { oea { manifestPlaceholders = [APP_NAME: "APP_OEA"] } oeb { manifestPlaceholders = [APP_NAME: "APP_OEB"] } }
这样打不同的包就会出现不同的名称。
APP图标、UI
其实还有一个知识没有介绍,留到这里是为了配合这个需求。那就是分module
进行依赖。
module
来分开放置。但是如何把不同的oe和不同的module
关联起来呢? 现在我们有2个oe:oea oeb productFlavors { oea { } oeb { } }
然后新建两个module
分别叫oea oeb
QQ截图20170815110128.png
关键代码:
dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) oeaCompile project(':oea') oebCompile project(':oeb')}
xxCompile
代表使用productFlavors
的名称(这里就是oea
),将flavor
和module
关联起来。
oea
包的时候依赖oea
这个module 打oeb
包的时候依赖oeb
这个module 好了现在可以在不同的module中放置同名的资源,然后打不同包的时候就可以自动切换成不同的资源依赖了!
比如我们的APP图标,声明在manifest中那么我们就在两个module
中放入同名的图标文件,注意在主module
(app)中反而要删除。
QQ截图20170815132915.png
最终效果:
QQ截图20170815133346.png
UI
同样使用上面的方法,可以实现整套图片素材、颜色、string中的文字描述等等的全部替换。
甚至还可以根据不同的oem使用不同的业务逻辑。 具体做法: 在productFlavors
中声明一个变量,根据这个变量来更改业务逻辑。 gradle中: productFlavors { oea { buildConfigField 'String', 'OEM', '"OEA"' } oeb { buildConfigField 'String', 'OEM', '"OEB"' } }
java中:
switch (BuildConfig.OEM) { case "OEA": break; case "OEB": break; }
源码demo已上传到。谢谢大家~
作者:_Janus 链接:http://www.jianshu.com/p/ce50e5c74a48 來源:简书 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。