在平时的Android开发中 。我们经常会遇到在不同网络环境(比如:开发环境、测试环境)之间的切换、一次打多个渠道包等需求 。如何优雅的管理网络环境的配置?如何快速的打出多个渠道包?这是一个值得研究的问题 。如果每一次在不同网络环境间切换 。都需要更改代码 。然而重新打包 。那未免有点低效 。下面是我的实践探索 。看网上很多人都是根据buildType来切换网络环境 。感觉有点不好 。因为网络环境可能很多种 。而buildType我们一般是2种 。而且 。不同网络环境的包最好能同时安装在手机上 。以便我们调试 。最好 。我一看这个包的名称和图标 。就能知道这是什么环境的包 。
一、概述
1.多版本
基于buildTypes
(1)debug:调试版本,无混淆
(2)release:发布版本,有混淆、压缩
2.多环境
基于productFlavors
(1)develop:开发环境 。开发和自测时使用
(2)check:测试环境 。克隆一份生产环境的配置 。在这里测试通过后 。再发布到生产环境 。
之所以没命名为test是因为在gradle编译时:ProductFlavor names cannot start with ‘test’
(3)product:生产环境 。正式提供服务的 。
3.多渠道
基于Android新的应用签名方案APK Signature Scheme v2中的APK Signing Block区块
我这里使用的是美团封装的Walle库 。使用Walle库请确保你的Android Gradle 插件版本在2.2.0以上 。
为什么不直接使用productFlavors来打包多渠道?因为productFlavors打多渠道包太慢了 。打30个包差不多十几分钟 。无法忍受!
为什么不使用美团之前基于META-INF进行渠道标识的方案?因为Android7.0之后的这种黑科技已经失效了!
二、示例
1、配置build.gradle
(1) 在位于项目的根目录 build.gradle 文件中添加Walle Gradle插件的依赖 。如下:
buildscript{dependencies{classpath'com.android.tools.build:gradle:2.2.3'classpath'com.meituan.android.walle:plugin:1.0.3'}}
(2) 在当前app的 build.gradle 文件中apply这个插件 。并添加上用于读取渠道号的aar
applyplugin:'com.android.application'applyplugin:'walle'android{compileSdkVersion25buildToolsVersion"25.0.2"defaultConfig{minSdkVersion15targetSdkVersion25versionCode1versionName"1.0"testInstrumentationRunner"android.support.test.runner.AndroidJUnitRunner"}signingConfigs{release{keyAliasKEY_ALIASkeyPasswordKEY_PASSWORDstoreFilerootProject.file(KEYSTORE_FILE)storePasswordKEYSTORE_PASSWORD}}buildTypes{//调试版本 。无混淆debug{minifyEnabledfalsesigningConfigsigningConfigs.release}//发布版本 。有混淆release{minifyEnabledtruezipAlignEnabledtrueshrinkResourcestruesigningConfigsigningConfigs.releaseproguardFilesgetDefaultProguardFile('proguard-android.txt'),'proguard-rules.pro'}}productFlavors{//开发环境develop{buildConfigField"int","ENV_TYPE","1"applicationId'om.soubu.walledemo.develop'manifestPlaceholders=[app_name:"开-WalleDemo",app_icon:"@drawable/icon_develop"]}//测试环境check{buildConfigField"int","ENV_TYPE","2"applicationId'om.soubu.walledemo.check'manifestPlaceholders=[app_name:"测-WalleDemo",app_icon:"@drawable/icon_check"]}//生产环境product{buildConfigField"int","ENV_TYPE","3"applicationId'com.soubu.walledemo.product'manifestPlaceholders=[app_name:"WalleDemo",app_icon:"@drawable/icon_product"]}}}dependencies{compilefileTree(dir:'libs',include:['*.jar'])androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2',{excludegroup:'com.android.support',module:'support-annotations'})compile'com.android.support:appcompat-v7:25.1.0'testCompile'junit:junit:4.12'compile'com.meituan.android.walle:library:1.0.3'}
(3) 这里 。我根据不同的环境生成了不同包名的apk 。方便在手机上同时安装多个环境的应用 。为了让gradle动态更改apk的名称和图标 。我们需要在manifest文件中使用
文章插图
文章插图
{app_name}等占位符
<?xmlversion="1.0"encoding="utf-8"?><manifestxmlns:android="http://schemas.android.com/apk/res/android"package="com.soubu.walledemo"><applicationandroid:allowBackup="true"android:icon="${app_icon}"android:label="${app_name}"android:supportsRtl="true"android:theme="@style/AppTheme"><activityandroid:name=".MainActivity"><intent-filter><actionandroid:name="android.intent.action.MAIN"/><categoryandroid:name="android.intent.category.LAUNCHER"/></intent-filter></activity></application></manifest>
(4) 在代码中获取多渠道信息
Stringchannel=WalleChannelReader.getChannel(getApplicationContext());
(5) 在代码中获取多环境信息
intenvType=BuildConfig.ENV_TYPE;
这里的BuildConfig是由gradle动态生成的:
packagecom.soubu.walledemo;publicfinalclassBuildConfig{publicstaticfinalbooleanDEBUG=Boolean.parseBoolean("true");publicstaticfinalStringAPPLICATION_ID="om.soubu.walledemo.develop";publicstaticfinalStringBUILD_TYPE="debug";publicstaticfinalStringFLAVOR="develop";publicstaticfinalintVERSION_CODE=1;publicstaticfinalStringVERSION_NAME="1.0";//Fieldsfromproductflavor:developpublicstaticfinalintENV_TYPE=1;}
而ENV_TYPE这个字段其实就来自于我们的build.gradle:
productFlavors{//开发环境develop{buildConfigField"int","ENV_TYPE","1"applicationId'om.soubu.walledemo.develop'manifestPlaceholders=[app_name:"开-WalleDemo",app_icon:"@drawable/icon_develop"]}{
这里我们最好定义一个常量类区分这些环境的类型:
publicclassEnvType{publicstaticfinalintDEVELOP=1;//开发环境publicstaticfinalintCHECK=2;//测试环境publicstaticfinalintPRODUCT=3;//正式环境}
2、打包多环境
这里我们直接执行assemble命令 。打包所有的buildType*productFlavors
文章插图
文章插图
或者使用命令行也可以:
gradle assemble执行结果:26秒搞定6个包:2个版本*3个环境
【Android android多渠道打包配置】
文章插图
文章插图
文章插图
文章插图
这里我们可以看到debug包都是1.4M,而release包都是0.7M 。显然 。我们的混淆和压缩配置是生效了的 。虽然这里我并没写混淆规则
文章插图
文章插图
文章插图
文章插图
我们分别安装3个环境的包到自己的手机上:
文章插图
文章插图
看三个包的名称和图标都不一样 。显然我们之前在manifest文件中配置的占位符生效了 。
然后我们点进去分别看看这3个app的区别:
文章插图
文章插图
文章插图
文章插图
文章插图
文章插图
这样 。我们就可以在代码中 。根据环境字段envType的不同 。来选择不同的网络环境了 。
界面的代码如下:
publicclassMainActivityextendsAppCompatActivity{@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);TextViewtvEnv=(TextView)findViewById(R.id.tv_env);TextViewtvChannel=(TextView)findViewById(R.id.tv_channel);TextViewtvPackage=(TextView)findViewById(R.id.tv_package);Stringchannel=WalleChannelReader.getChannel(this.getApplicationContext());intenvType=BuildConfig.ENV_TYPE;StringpackageName=getPackageName();switch(envType){caseEnvType.DEVELOP:tvEnv.setText("envType="+"开发环境");break;caseEnvType.CHECK:tvEnv.setText("envType="+"测试环境");break;caseEnvType.PRODUCT:tvEnv.setText("envType="+"生产环境");break;}tvChannel.setText("channel="+channel);tvPackage.setText("package="+packageName);}}
3、打包多渠道
在Project的根目录下新建channel文件:
anzhi#安智baidu#百度huawei#华为oppo#oppowdj#豌豆荚xiaomi#小米yyb#应用宝
执行gradle命令:
(1) 打包文件内的渠道包
gradle assembleProductRelease -PchannelFile=channel(2) 打包自定义数组内的渠道包
gradle assembleProductRelease -PchannelList=qihu,vivo,lenovo关于Walle库的更多使用:详见Github-walle
运行结果:17秒搞定8个包:1个默认包+7个渠道包
文章插图
文章插图
文章插图
文章插图
最后 。奉上源码:WalleDemo
常见问题
1、找不到签名文件的配置?
文章插图
文章插图
汗 。因为我的Demo中并没有上传我的jks文件 。你可以添加自己的jks文件 。然后在gradle.properties里面配置好签名文件的密码即可
在gradle.properties添加签名文件的配置key-value
文章插图
文章插图
在build.gradle中引用配置的key
文章插图
文章插图
2、develop、check、product 。如果直接run代码 。怎么设置默认的环境?
点击查看AndroidStudio左下角的BuildVariants 。然后选择设置默认的run环境即可 。
BuildVariants= buildTypes* productFlavors
文章插图
文章插图
文末送福利啦!!
同时我经过多年的收藏目前也算收集到了一套完整的学习资料以及高清详细的Android架构进阶学习导图及笔记免费分享给大家 。希望对想成为架构师的朋友有一定的参考和帮助 。
**下面是部分资料截图 。诚意满满:特别适合有开发经验的Android程序员们学习 。
文章插图
文章插图
- Android音频开发 android音乐播放器的实现
- Android背景设置透明和半透明效果 android背景透明度怎么设置
- Android是什么牌手机 android是什么牌手机
- 历代Android版本彩蛋回顾 android版本10隐藏彩蛋
- iQOO 7同步适配Android 12.0 版本 第一时间供开发者体验尝鲜
- 央行:金融体系保持稳健运行 中小银行多渠道补充资本金取得新进展
- 汇承金融科技:开创多渠道资产与资金撮合融资服务模式
- 政府工作报告:稳定和扩大消费。多渠道增加居民收入