1. 概述
简单网络时间协议(Simple Network Time Protocol),由 NTP 改编而来,主要用来同步因特网中的计算机时钟。
NTP 协议可以跨越各种平台和操作系统,用非常精密的算法,因而几乎不受网络的延迟和抖动的影响,可以提供1-50 ms 精度。NTP 同时提供认证机制,安全级别很高。但是NTP 算法复杂,对系统要求较高。
SNTP(简单网络时间协议)是NTP 的简化版本,在实现时,计算时间用了简单的算法,性能较高。而精确度一般也能达到1 秒左右,也能基本满足绝大多数场合的需要。所以SNTP通常是用于网络中叶子节点设备的时间同步,因为通常该站点对时间精度的要求并不是非常高。
2. 框架分析
2.1类图
时间同步这个框架,是非常简单,类图见如下,就由三个类组成。其作用见如下类的说明。
类SystemServer.java
系统服务管理,启动NetworkTimeUpdateService服务
类NetworkTimeUpdateService.java
网络时间更新服务,用于控制系统何时发起时间同步。
mPollingIntervalMs:用于给定时器的多少时间来同步时间,系统当前是24H
mPollingIntervalShorterMs:在时间同步失败后,通过再起定时器来同步系统时间,系统当前时间是5S。
mTryAgainTimesMax:最大尝试时间同步的次数,系统当前次数是8次。
mTimeErrorThresholdMs:系统当前时间与网络时间如果大于这两者的绝对差值,就会把网络时间更新到当前的系统时间,绝对差值当前是5S。
mNtpBackupServerList:展锐做的一个功能,如果在定时网络时间同步失败后,就启用逐个访问SNTP服务器。
类NtpTrustedTime.java
提供Sntp接口及服务。
mHasCache:用于标示是否同步时间获取
mCachedNtpTime:NTP对时成功的时间。
mCachedNtpElapsedRealtime:获取到网络时间时当前系统开机以来的毫米数,包括睡眠。
mCachedNtpCertainty:
类SntpClient.java
Sntp时间获取,通过socket跟服务器获取时间。
2.2时序图
触发时间同步函数调用也很简单,结合代码及时序图,主要过程如下:
- 监听自动时间同步数据库:这种情况是设置里面打开了自动对时功能的话,会触发消息EVENT_AUTO_TIME_CHANGED来调用onPollNetworkTime。
- 自动时间同步定时器超时:这个是系统设置了个定时器,如12H自动触发对时,对应的消息是EVENT_POLL_NETWORK_TIME,然后调用onPollNetworkTime。
- 网络状态有变化:如果网络IP有变化或网络出现了重连,会触发消息EVENT_NETWORK_CONNECTED来调用onPollNetworkTime。
onPollNetworkTime的作用是根据条件情况,满不满足进行对时。
forceRefresh用于提供对时接口给NetworkTimeUpdateService
requestTime用于Sntp请求网络获取时间。
2.3流程图
整个流程调用其实是很简单,可是没想到触发时间同步的逻辑上竟是那么复杂,好多的if判断,好多的变量。关于变量,类图上已说的差不多。上图就是onPollNetworkTime函数的处理过程。
2.3.1事件注册
当类NetworkTimeUpdateService的systemRunning函数被调用时,会向系统注册三个消息,见上面代码,已使用红色框框出来。消息分别是EVENT_AUTO_TIME_CHANGED、EVENT_POLL_NETWORK_TIME、EVENT_NETWORK_CONNECTED。这三个消息的作用也讲过,这里不再说明。这三个消息就是触发时间同步逻辑的开始条件。而一旦有任何一个消息被触发时,就会调用onPollNetworkTime函数。
2.3.2 onPollNetworkTime函数
此函数是控制时间同步是否触发的核心,个人总结可以分如下代码段来分析。
1、条件过滤
2、时间同步
mTime.getCacheAge() >= mPollingIntervalMs这行代码意思上次的NTP对时后到现在的时间差是否大于mPollingIntervalMs,mPollingIntervalMs当前系统是24H。如果条件达到,就进行时间同步。
3、更新系统时间
mTime.getCacheAge() < mPollingIntervalMs,这行代码要结合时间同步的步来看,因为如果时间同步成功了,mTime.getCacheAge()会更新为当前的系统开机时间,如果同时间同步失败,不会更新,还是上一次的系统开机时间。所以如果时间同步成功了,时间肯定会小于mPollingIntervalMs值。
4、时间同步失败
3总结
以上就是时间同步的逻辑,总结流程简单,但逻辑复杂。
4相关代码路径
NetworkTimeUpdateService.java:frameworks\base\services\java\com\android\server\
SntpClient.java:frameworks\base\core\java\android\net
NtpTrustedTime.java:frameworks\base\core\java\android\util
配置文件:frameworks\base\core\res\res\values\config.xml