小明一个刚入行安卓的小萌新,刚刚在测试小姐姐那里交过学费(挨过骂)了解到软件开发过程中是需要区分正式、测试环境的。但是他稍加思考就能想到测试、正式环境的区别仅仅是host不一样而已,其他的比如接口名、参数名、返回的json格式均一模一样。于是他马上找到了解决方案,平时都用测试环境的,到上线的时候再换回正式环境不就可以了?在一次开发中需要请求三个不同接口,说干就干,于是小明就写出了以下代码,准备在上线时全局搜索www.test.com改成www.release.com,提交以后开开心心下班撩妹去了。

//请求接口1
NetWorkUtil.request("http://www.test.com?action=a1")//请求接口2
NetWorkUtil.request("http://www.test.com?action=a2")//请求接口3
NetWorkUtil.request("http://www.test.com?action=a3")复制代码

三天以后,产品经理跑过来说要加一个需求,新增了好几个接口,小明表示自己表现的机会到了,一股脑儿全部包下来了。可是做着做着发现有点不对劲啊,每次请求接口的时候都需要复制http://www.test.com这个域名,可是产品锦鲤追的紧啊,没办法先就这么办吧,实现了需求上线以后再说。

一周过去了,上线时间到了。测试小姐姐又跑过来问小明这个正式包的数据怎么不对,还是测试环境的?小明赶紧道歉,想起来了上线前需要修改域名这个事情,自己居然忘记了。心里一万只草泥马飞过,小明赶紧的匆匆忙忙地改完项目里所有接口请求的地方,这才松一口气,给测试小姐姐买了个奶茶打了个新包,这个版本终于成功上线了,还真是不容易啊。

一天以后,小明被项目经理叫到了办公室,把小明狠狠批了一顿。原来是小明有个地方忘记改了,线上用户的操作被记录到了测试数据库了。项目经理为了解决这个问题,将最近一天测试环境的该数据全部导入到了正式环境才解决,当然还收到了不少的投诉。不过还好这个数据不是核心数据,不是那么重要,不然小明的机票估摸着差不多就到手了。

小明痛定思痛,坚决要杜绝这种低级错误。于是他把需要改域名这个事情已经记录到备忘录里每天提醒了,除此之外,聪明的他还想到了一个办法,就是用一个全局的变量对域名进行保存,在上线前只需要切换一次就行了,类似于这种:

companion object {    const val HOST = "http://www.test.com"
}
override fun onCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) {    setContentView(R.layout.activity_main)//请求接口1NetWorkUtil.request("$HOST?action=a1")//请求接口2NetWorkUtil.request("$HOST?action=a2")//请求接口3    NetWorkUtil.request("$HOST?action=a3")
}复制代码

小明终于没有犯线上的低级错误了,但是后面业务需求越来越繁杂,服务端使用的域名也越来越多,并且很多第三方的api比如推送、bugly监测等也都需要切换id。每次上线需要修改一堆的域名和id。小明每天心态都跟高考一样,紧张又害怕,生怕自己再出问题,被强制送机票。而且就算在测试阶段,测试小姐姐偶尔也会让他打一个release包测试,虽然心里千万只草泥马不愿意,但是也没办法,先改成线上的域名吧,打完以后再改回来呗!于是小小明逐渐地熟悉了这一套切换方式,直到他看到了那一篇技术博客,小明他。。。哭了。

熟练开发者是怎么做的

小明看到的文章正是一篇关于测试和正式环境切换的技术文章,该文通俗易懂,还提供了完整的方案,小明看完觉得这不就是为自己准备的么,于是按照文章里的方式尝试了起来。文章中说到可以根据当前app是debug还是release来切换host,大概实现如下,首先在Application的onCreate()中获取到当前是否是debug模式,并且用静态变量进行记录,接下来需要区分测试、正式环境的时候就根据这个flag来判断即可。

class MyApplication: Application() {companion object {var IS_DEBUG = true}override fun onCreate() {super.onCreate()IS_DEBUG =  (applicationInfo.flags != 0 && ApplicationInfo.FLAG_DEBUGGABLE != 0)}}复制代码

小明收到了该文章的启发,于是在项目所有需要区分测试、正式环境的地方都对上面的flag进行了判断,其代码大致如下:

companion object {val HOST1 = if(MyApplication.IS_DEBUG)"http://www.test1.com" else "http://www.release1.com"val HOST2 = if(MyApplication.IS_DEBUG)"http://www.test2.com" else "http://www.release2.com"val HOST3 = if(MyApplication.IS_DEBUG)"http://www.test3.com" else "http://www.release3.com"}复制代码

到了这里终于小明终于可以松口气不用设置备忘录,每次上线不用为了改域名问题而提心吊胆了,域名会智能地根据当前是debug包还是release包还自动赋值。但是后面加在这里的域名和第三方api越来越多,于是小明还在此基础上举一反三,进行了一波优化。小明了解到在系统打包的时候,如果在build.gradle文件中的buildTypes里添加debug和release的相应配置,系统在build/generated/source/buildConfig目录下会自动生成BuildConfig类,系统自动生成的类大概如下:

/*** Automatically generated file. DO NOT MODIFY*/
package xx.xx.xx;public final class BuildConfig {public static final boolean DEBUG = false;public static final String APPLICATION_ID = "xx.xx.xx";public static final String BUILD_TYPE = "debug";public static final String FLAVOR = "";public static final int VERSION_CODE = 1;public static final String VERSION_NAME = "1.0";
}
复制代码

这里面的字段是可以添加的,比如在build.gradle中设置好需要区分测试、正式环境的host,可以先按如下规则定义好

buildTypes {debug {buildConfigField "String", "URL", "\"www.test.com\""}release {buildConfigField "String", "URL", "\"www.release.com\""}
}
复制代码

则在编译的时候,系统会自动在BuildConfig中加入以下代码

public static final boolean DEBUG = true;

public static final String URL= "www.test.com";//如果是release包中会自动生成www.release.com

我们可以看到,在实际开发的时候根本不需要去设置当前是哪个域名,而是系统会自动来判断,从而在实际的业务需求开发时我们只需要使用BuildConfig.URL即可,小明将所有的域名以及第三方sdk需要的appkey都放到了buildTypes里,于是小明的代码可以改成这样子了:

//请求接口1
NetWorkUtil.request("${BuildConfig.URL}?action=a1")//请求接口2
NetWorkUtil.request("${BuildConfig.URL}?action=a2")//请求接口3
NetWorkUtil.request("${BuildConfig.URL}?action=a3")复制代码

当然这里URL最好封装到Common层中,这里就不多说,不是本文的重点。经过这一波的修改终于不用在每次上线时都修改URL了,而是系统会自动选择好URL,我们直接使用就可以了。

如何优雅的区分测试版本和正式版本的环境相关推荐

  1. maven中snapshot版本和正式版本的区别

    参考链接:https://www.cnblogs.com/huang0925/p/5169624.html 理解Maven中的SNAPSHOT版本和正式版本 Maven中建立的依赖管理方式基本已成为J ...

  2. 理解Maven中的SNAPSHOT版本和正式版本

    Maven中建立的依赖管理方式基本已成为Java语言依赖管理的事实标准,Maven的替代者Gradle也基本沿用了Maven的依赖管理机制.在Maven依赖管理中,唯一标识一个依赖项是由该依赖项的三个 ...

  3. maven快照版本和发布版本

    在使用maven过程中,我们在开发阶段经常性的会有很多公共库处于不稳定状态,随时需要修改并发布,可能一天就要发布一次,遇到bug时,甚至一天要发布N次.我们知道,maven的依赖管理是基于版本管理的, ...

  4. 快照版本和发布版本区别

    在使用maven过程中,我们在开发阶段经常性的会有很多公共库处于不稳定状态,随时需要修改并发布,可能一天就要发布一次,遇到bug时,甚至一天要发布N次.我们知道,maven的依赖管理是基于版本管理的, ...

  5. vue cli3 一键 build 区分测试环境和正式环境

    vue cli3 打包 build 区分测试环境和正式环境 通过自定义环境变量文件进行配置 思路: 默认情况下,执行 npm run serve 会以 development 的模式启动 执行 npm ...

  6. 传阿里云盘将开启扩容收费测试:200GB售价 108元/年;偷车贼使用苹果 AirTag 追踪想要盗走的高档汽车;Visual Studio 2022和 .NET 6正式版本发布|极客头条

    一分钟速览新闻点! 阿里张勇发内部信:武卫不再担任阿里巴巴集团 CFO 传阿里云盘将开启扩容收费测试:200GB 售价 108 元/年 元宇宙领域出现最新招标!中国电信子公司拟采购"元宇宙数 ...

  7. mysqlsql varchar类型只取前四个_Apache Doris0.12.0 发布,进入 Apache 孵化器后第四个正式版本...

    Apache Doris(Incubating) 0.12.0 已经发布了,这是 Doris 进入 Apache 孵化器后第四个正式版本. 此版本带来的新功能包括: 全新的存储格式SegmentV2 ...

  8. 最新绝地求生服务器中文版,绝地求生正式版本服务器翻译最新 | 手游网游页游攻略大全...

    发布时间:2017-01-24 随着版本的更新,地图与资源分布也会逐步的变化,今天小编带来"抱朴提灯"分享的最新资源分布地图,有需要的玩家跟小编一起来看吧. 注:请点击查看 ... ...

  9. 十年来第一个正式版本 | Kali Linux 2020 发布后我们该怎么渗透?

    2020年Kali Linux推出了十年来的第一个正式版本--Kali Linux 2020.1 关于这个版本新特性的简短总结: 默认用户为非root用户 独立的Kali安装镜像 无需root的Kal ...

最新文章

  1. linux修改ssh端口
  2. libevent中的bufferevent
  3. sqlserver 两表联查去重_去山东省(烟台)必吃“特色”小吃 ,舌尖5大美食享受!...
  4. 02.centos6.4找不到ifcfg-eth0(静态ip配置)
  5. VMware安装Linux ubuntu虚拟机
  6. poj1236-Tarjan算法
  7. SAP CDS view自学教程之六:如何在CDS view里消费table function
  8. mac php mcrypt,MacOSX 10.10安装mcrypt详细教程分享
  9. curl请求命令url加引号
  10. USACO3.22Stringsobits
  11. asp.net 2.0常见问题技巧1
  12. 假如 C++ 是一只箭,你会用它来射哪只雕?
  13. oracle的sql口令,Oracle数据库的SYS口令是什么?
  14. 王彪20162321 2016-2017-2 《程序设计与数据结构》第6周学习总结
  15. paip.c#使用匿名函数建立委托提高可读性
  16. 杀毒软件可能令企业用户陷入更大危机
  17. Web CAD SDK 14.1.0 New Crack
  18. php php拼接字符串函数_PHP_PHP开发中常用的字符串操作函数,1,拼接字符串 拼接字符串是最 - phpStudy...
  19. python在视频上方加字_python 使用 MoviePy 给视频添加文字水印demo实现[附代码]
  20. 全国高校计算机能力挑战赛真题(一)

热门文章

  1. [Android]在App中使用相机
  2. 音频Codec标准组织
  3. 知到网课你不知道的毒品真相期末考试单元答案
  4. IP网络存储iSCSI之一iSCS的概念、组成及工作原理
  5. java实现九九乘法表算法
  6. 小米机型TWRP_recovery合集分享-支持米9等新机
  7. linux查看自动周期性任务,Linux自学笔记——Linux周期性计划任务
  8. WinXP原版与VOL版的区别
  9. Delphi 2010 里公开的 Midas.dll 的源代码!!
  10. 栈(stack) C语言实现 详解