问题点
越来越多的业务场景需要根据服务器时间进行本地的展示,就有了这样这样一些问题:
a. 服务器时间接口频繁调用。使用服务器时间的业务模块较多时,每次使用都要调用一次服务器时间接口;
b. 业务阻断。调用服务器时间期间,本地业务展示需等待服务端时间接口调用;
c. 服务端时间接口调用时的时间消耗。在调用服务器时间接口时存在网络上,以及服务器处理的时间消耗。
如何在误差允许范围内优化这些问题?
优化方案
现考虑如下一种优化方案:
- 服务器时间接口频繁调用和业务阻断。在APP启动时,调用服务端时间接口,计算服务端时间接口和本地时间差值,在使用服务器时间时根据差值和本地时间计算实际的服务器时间。
-
服务端时间接口调用时的时间消耗。参考NTP协议,可以优化这个问题。
NTP原理如下:
系统时钟同步的工作过程如下:
Device A发送一个NTP报文给Device B,该报文带有它离开Device A时的时间戳,该时间戳为10:00:00am(T1)。
当此NTP报文到达Device B时,Device B加上自己的时间戳,该时间戳为11:00:01am(T2)。
当此NTP报文离开Device B时,Device B再加上自己的时间戳,该时间戳为11:00:02am(T3)。
当Device A接收到该响应报文时,Device A的本地时间为10:00:03am(T4)。
至此,Device A已经拥有足够的信息来计算两个重要的参数:
NTP报文的往返时延Delay=(T4-T1)-(T3-T2)=2秒。
Device A相对Device B的时间差offset=((T2-T1)+(T3-T4))/2=1小时。
存在的问题
如果用户切到后台修改了本地时间,或者通过其他方式同步了客户端时间,会造成最终获取到的时间存在误差。
可采用如下两种方式进行优化:
- 监听时间修改;
- 使用SystemClock.elapsedRealtime()。SystemClock.elapsedRealtime()获取的时间时从手机boot后到现在的时间,跟系统时间设置无关。