如今互联网开发都处于快速迭代开发的状态。这里咱们来讨论一下迭代开发中的生命周期,代码版本,兼容性设计等话题。html
一般,一个产品都具备两个环境:java
而每一个版本的生命周期一般会经历以下几个阶段(忽略需求和设计等辅助阶段):git
因此针对APP,可能会出现同一个时间,线上存在多个不一样版本的APP。因此咱们须要注意:sql
在开发过程当中,会遇到代码版本的管理问题,好比说:一个线上的BUG,如何进行修改和发布。这须要一个合理的代码版本管理。数据库
一般,咱们会采用x.y.z的格式来定义版本号,而考虑到机器和人的区别,出现了两种方式的版本号定义:api
versionName的公式为:安全
versionName = x.y.z , 且 x.y.z 都为数字服务器
versionCode计算公式为:网络
versionCode = x * 10000 + y * 100 + z 的格式命名数据结构
一般采用versionCode做为系统内部的版本对比数值
代码版本结构(采用git管理):
/tag 标签 /tag-v1.0.0 v1.0.0版本 /tag-v1.0.1 v1.0.1版本, 修复了v1.0.0版本的某些BUG /branch 分支 /master 最后一次发布的代码版本,发布完成后须要打tag /dev-v2.0.0 v2.0.0 版本开发分支 /dev-v2.0.0-{todo} v2.0.0 todo功能开发分支,开发完成后,merge到dev-v2.0.0中 /fix-v1.0.2 v1.0.2 版本修复分支 /test-{todo} 实验性质的分支,不一样步到repo上
注意:对于Android APP的发布后,打tag的时候须要上传apk和mapping文件,方便以后定位线上bug
这里写一些通用的概念:
在保持兼容的过程当中,服务器的兼容性仍是比较好处理的,由于服务器的升级彻底处于咱们本身的控制中, 不会出现服务器处于不一样的版本状态。因此,只要处理好**数据库,HTTP接口,推送协议,**基本能保证 迭代无反作用。
在业务的开发过程当中,不可避免的就是添加新的字段和删除原来旧的字段,对于新的字段添加,基本上可 以保证旧的业务正常的运行,而删除字段,则可能致使旧的业务不能正常的运行,因此须要慎重选择。 固然咱们也不是不能删除字段,通常的作法是先保留旧的字段,而后等待APP版本废弃,以后就可 以进行删除该字段了。
对于HTTP接口,在迭代过程当中,会出现以下几种状况:
这几种状况,为了保证已经上线的APP能正常的运行,因此咱们须要对API作兼容性工做。API格式为:
当对一个API进行更新的时候,而且没法作到兼容的时候(删除字段等),咱们新建一个
这种格式的API,而且使用注解标记原先API为废弃状态(禁止新开发版本使用该API,而且版本迭代 到后面几个版本后,能够剔除该API)。这种API设计方式有以下的优势:
然而,这种方式有一个缺点:对同一个API修改的次数过多,会致使造成过多的 API 版本(1,2,3,4,5) 不是很是的好看,咱们能够经过设置一个版本滑动窗口来解决。
版本滑动窗口:当API版本迭代到10的时候,自动又从0开始,固然了0版本号的api须要早早的被废弃掉。
固然,还有其余解决URL兼容性的方法,好比说:采用http://host/v1/module/service 的方式,可是这个方式存在一个比较致命的地方:每次修改API,都须要FORK出新的代码版本,而每每咱们还须要维护旧版本代码,致使维护难度(修改同一个API的时候,须要打开该API的多个代码版本进行维护)。
固然了,若是是删除字段的API,咱们也能够仅仅标记这个API中的某个字段被废弃,新版本APP不在使用这个API的这个删除字段,而后等待使用该字段的APP版本废弃就能够真实的删除这个字段了。这个方法的优势就是不须要新建立一个API,缺点就是删除字段的时候比较麻烦。
不只仅是API的URL须要保持兼容性,针对返回的数据,咱们也须要作到必定程度的扩展性。
例子一 : 朋友圈主题不一样类型
在最先的时候,朋友圈仍是只能处于发发图片和文字的状态,后来加入了一些额外的元素, 如音乐,视频,图文等内容。然而在加入了新的主题类型后,旧的用户不必定会立刻升级, 因此要保持朋友圈的兼容性。有大体两个作法:
方案1虽说也能处理这些状况,可是整体来讲没有方案2来的更加优雅。
对于HTTP接口设计中身份验证,一般采用TOKEN的方式。由于TOKEN比较方便存储,以及显示的使用。
HTTP 返回的数据格式,一般采用JSON格式:{code:-1|0|1,msg:String,data:any}。
为了通讯的安全,咱们还须要采用HTTPS链接方式,避免中间人攻击等常见的网络攻击手段。
开发移动APP的时候,不可避免的就是使用长链接推送一些及时消息,好比说新闻,广告,强制下线通知等。而推送协议的格式基本上为:
{ module: 模块类型, function:操做类型, [data]:{msg:"hello world"}}。
当APP端接收到推送的时候。采用以下的步骤处理推送:
处理过程当中,注意使用
try{ ...logic }catch(Exception e){ }
避免处理过程当中,致使APP奔溃。
当出现推送协议彻底不兼容(删除字段等)的状况的时候,咱们须要针对推送协议作兼容处理,一般咱们能够采用function[..N]的方式来兼容。在兼容期阶段,咱们能够采用:
上述两种方法各有优缺点:方案1比较智能,可是开发量比较大。而方案二比较方便,可是比较损耗流量。而方案3须要时间来过分。
针对删除字段的状况,咱们也能够和URL兼容同样,标记这个字段被废弃,新版本APP再也不使用这个删除的字段,维持一段时间继续推送这个字段,当使用该字段的APP版本废弃后,就能够删除这个字段不进行推送了。这个方法的优势就是能比较完美的兼容以前的协议,可是缺点就是删除字段的时候比较麻烦。
移动端升级,主要涉及到**本地数据(数据库,磁盘文件),APP全局升级补丁,协议兼容性(HTTP,推送), 以及APP版本检测,**而JAVA代码和资源文件,固然就不须要进行处理了。
数据库升级仍是比较方便的,这里咱们采用APP版本代码(versionCode)做为SQLite的版本号, SQLite已经为咱们提供好了onUpgrade接口,在升级的时候,SQLite会给出旧的版本号,和最新的版本号, 此时咱们只要作:
就能够保证对数据库的正确升级了。
除了数据库升级,对于磁盘文件,升级后的引导页面等须要处理的杂项,能够在APP全局升级补丁中进行 处理。好比说,某个版本,能够删除某些磁盘文件,那么,就能够在全局补丁中编写代码。具体的作法为:
升级代码大体以下:
能够发现,使用versionCode做为升级代码点,能比较清晰的区分出不一样版本作了什么事情。并且对于从比较老的版本直接升级过来,也是OK的。
APP版本检测和是升级是比较核心的功能模块。主要实现的功能有:
因此,APP检测的时候,给定服务器最新的版本信息数据便可,格式基本是这个样子:
含义:
当检测到新的APP版本后,还须要在界面上进行ALERT,通知用户进行升级。强制升级的话,须要禁用全部 的功能(避免APP奔溃)。而后进行ALERT用户。
APP版本检测功能,应该算是APP快速迭代的保证。可让服务端来控制APP是否能够继续使用和升级。
固然了,还有一些其余方面的迭代开发话题,以后再补充上去。