跑步机底层重构的背景,以及为什么需要重构

之前的方式

  1. 对于每个机型都做分渠道,每个渠道都有对应的不同的java文件对底层控制,及每个机型的配置文件
    好处:很快能适配某一特定驱动厂商的机型
    坏处:对于其他驱动厂商的机型适配时不得不另开一个分支去开发,而且不同驱动厂商的不能合并到主分支上,以后发版只能从主分支合并到feature分支上,由于控制逻辑不同,可能会伴随着冲突
    每种驱动厂商对应的控制跑步机,以及对跑步机的响应状态的都是不一样的

  2. 随着跑步机的机型越来越多,每个机型的测试,每个机型都需要测试,导致占用的时间也越来越多,每次发版时间周期冗长(但是又是不可避免的),对于控制的部分,合作厂商要求比较严格,对于业务部分还可以商量。

抽象过程

对别人app的反编译,阅读他们的代码,可以发现,底层主要的功能分为四大块

  1. 机器的控制
  2. 状态的回调
  3. 数据的回调
  4. 物理按键分发

对于不同的驱动厂商提供的api来说,一定会存在差异,计算机界有一句名言:“计算机科学领域的任何问题都可以通过增加一个中间层来解决。”(原始版本出自计算机科学家 David Wheeler)我们也添加中间层和接口来屏蔽不同差异

ITreadmillManager是实际控制跑步机的接口

鉴丰驱动包含

  1. 500ms轮询读取485数据和232按键数据(电机下控错误,电源板上的安全锁),分发到上层,485主要是读取步数,主板上的安全锁开关等数据,两个安全锁是因为相关规定安全锁必须在电源板上,而之前在上控板上的安全锁被焊死了,a6s还是上控板上。
  2. 提供供上层调用向串口写数据的接口:速度,开始,停止,加速,减速,加坡度,减坡度
  3. 提供数据回调,状态回调
  4. 按键led的控制
  5. 速度坡度的广播

易步驱动包含:

  1. 500ms轮询从framwork的service当中数据
  2. 从framwork发出的广播执行相应的响应
  3. 向上层提供启动停止,设置速度,坡度,加速,减速,加坡度,减坡度
  4. 提供数据回调,状态回调

IDevice

创建的是不同的ITreadmillManager
向上层提供与ITreadmillManager类似的接口,但是没通过设置速度,坡度,加速,减速,加坡度,减坡度接口
而是通过上层向该层发送对应的指令,该层分发调用ITreadmillManager对应的指令。
设置数据,状态,按键监听

ISpaxDevices则是对外暴露的唯一接口
负责维护,数据,状态,按键监听的数据赠删。
创建不同的设备类型(目前就一种跑步机)

之前的设计的类图(参考),如下
类图

底层异常处理

底层的异常基本都在初始化失败,和读取配置文件失败上,对于这种错误,APP不能不理会,这样的话,只有底层抛出异常,由上层根据不同的异常做出不同的处理。

升级兼容相关问题

对于升级我们最稳定的一版还是按照分渠道打包,将配置文件的标致打入到app中,再根据配置文件的标识,创建出配置bean,将配置文件的信息载入到请求头,埋点中,低于该版本的必须先升级到该版本,才能继续升级到下一个版本。

APP工程结构相关

对这些抽象,我们想把他做成一个sdk,写好过后不再改动他,除非有新的机器来,所以该项目以submodle的方式引入我们我们的项目中

git submodle的优点是与主项目脱离,即你在主项目中修改了子模块里的文件,然后在主项项目提交,并不会将子模块的修改的源文件提交

这个在自动化部署上有比较明显的体现(本地能编译过,但是在teamcity就是缺一些方法,或者常量)

工程项目结构
common里
compileOnly files(‘libs/framework.jar’)
compileOnly files(‘libs/services.jar’)
就不会造成包的体积过过大,和android sdk不兼容引起的https和http问题
这样在app/build.gradle里直接

1
implementation project(':spax-devices-lib:common')

总结

这次是根据设计出类来后,再实际编码,做到心中有数,但是在上层的根据下层的调整做出的调整后,引发了一些问题

  1. 提前进入距离为0
  2. 数据由之前之前的4s一次上传的,变为2s,底层轮训速度改为500ms引起的