Android客户端与服务器时间同步

问题点

越来越多的业务场景需要根据服务器时间进行本地的展示,就有了这样这样一些问题:
a. 服务器时间接口频繁调用。使用服务器时间的业务模块较多时,每次使用都要调用一次服务器时间接口;
b. 业务阻断。调用服务器时间期间,本地业务展示需等待服务端时间接口调用;
c. 服务端时间接口调用时的时间消耗。在调用服务器时间接口时存在网络上,以及服务器处理的时间消耗。

如何在误差允许范围内优化这些问题?

优化方案

现考虑如下一种优化方案:

  1. 服务器时间接口频繁调用和业务阻断。在APP启动时,调用服务端时间接口,计算服务端时间接口和本地时间差值,在使用服务器时间时根据差值和本地时间计算实际的服务器时间。
  2. 服务端时间接口调用时的时间消耗。参考NTP协议,可以优化这个问题。
    NTP原理如下:

    《Android客户端与服务器时间同步》 1096626509281939420.jpg

    系统时钟同步的工作过程如下:
    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小时。

存在的问题

如果用户切到后台修改了本地时间,或者通过其他方式同步了客户端时间,会造成最终获取到的时间存在误差。
可采用如下两种方式进行优化:

  1. 监听时间修改;
  2. 使用SystemClock.elapsedRealtime()。SystemClock.elapsedRealtime()获取的时间时从手机boot后到现在的时间,跟系统时间设置无关。
    原文作者:dlobo
    原文地址: https://www.jianshu.com/p/bac0c154028f
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞