Android 时间同步服务NetworkTimeUpdateService

NTP介绍

NTP:网络时间协议,英文名称:Network Time Protocol(NTP)是用来使计算机时间同步化的一种协议,它可以使计算机对其服务器或时钟源(如石英钟,GPS等等)做同步化,它可以提供高精准度的时间校正(LAN上与标准间差小于1毫秒,WAN上几十毫秒),且可介由加密确认的方式来防止恶毒的协议攻击。NTP的目的是在无序的Internet环境中提供精确和健壮的时间服务。

Android系统使用NTP自动更新系统时间的触发机制有两种:

监听数据库字段AUTO_TIME,当这个字段发生变化的时候,会立即触发一次时间同步
网络连接发生变化,当网络接通,会触发一次时间检查和同步
定时更新机制,当预定的时间到了,会触发一次时间检查和同步

Android系统的使用NTP更新系统时间是在NetworkTimeUpdateService服务里面实现的,首先看一下服务的初始化过程。

NtpTrustedTime获取时间

mServer服务器名字,在初始化NtpTrustedTime时由config_ntpServer和NTP_SERVER共同制定

@frameworks/base/core/java/android/util/NtpTrustedTime.java
    private NtpTrustedTime(String server, long timeout) {
   
   
        if (LOGD) Log.d(TAG, "creating NtpTrustedTime using " + server);
        mServer = server;
        mTimeout = timeout;
    }

    public static synchronized NtpTrustedTime getInstance(Context context) {
   
   
        if (sSingleton == null) {
   
   
            final Resources res = context.getResources();
            final ContentResolver resolver = context.getContentResolver();

            final String defaultServer = res.getString(
                    com.android.internal.R.string.config_ntpServer);
            final long defaultTimeout = res.getInteger(
                    com.android.internal.R.integer.config_ntpTimeout);

            final String secureServer = Settings.Global.getString(
                    resolver, Settings.Global.NTP_SERVER);
            final long timeout = Settings.Global.getLong(
                    resolver, Settings.Global.NTP_TIMEOUT, defaultTimeout);

            final String server = secureServer != null ? secureServer : defaultServer;
            sSingleton = new NtpTrustedTime(server, timeout);
            sContext = context;
        }

        return sSingleton;
    }

ntp服务地址: https://www.cnblogs.com/configure/p/13469039.html

 <string translatable="false" name="config_ntpServer">time1.aliyun.com</string>

NtpService 调用forceRefresh获取时间,通过获取ConnectivityManager服务,SntpClient.requestTime来获取时间

@frameworks/base/core/java/android/util/NtpTrustedTime.java
@Override
public boolean forceRefresh() {
   
   
    // We can't do this at initialization time: ConnectivityService might not be running yet.
    synchronized (this) {
   
   
        if (mCM == null) {
   
   
            mCM = sContext.getSystemService(ConnectivityManager.class);
        }
    }

    final Network network = mCM == null ? null : mCM.getActiveNetwork();
    return forceRefresh(network);
}

public boolean forceRefresh(Network network) {
   
   
    if (TextUtils.isEmpty(mServer)) {
   
   
        // missing server, so no trusted time available
        return false;
    }

    // We can't do this at initialization time: ConnectivityService might not be running yet.
    synchronized (this) {
   
   
        if (mCM == null) {
   
   
            mCM = sContext.getSystemService(ConnectivityManager.class);
        }
    }

    final NetworkInfo ni = mCM == null ? null : mCM.getNetworkInfo(network);
    if (ni == null || !ni.isConnected()) {
   
   
        if (LOGD) Log.d(TAG, "forceRefresh: no connectivity");
        return false;
    }


    if (LOGD) Log.d(TAG, "forceRefresh() from cache miss");
    final SntpClient client = new SntpClient();
    if (client.requestTime(mServer, (int) mTimeout, network)
Android系统中,使用NTP获取时间可以通过以下方式: ### 系统服务调用 Android系统有相关系统服务类用于启动管理后续的系统服务,如`SystemServer.java`用于启动管理后续系统服务,其中`NetworkTimeUpdateService.java`会通过`onPollNetworkTime`调用`NtpTrustedTime.forceRefresh()`获取NTP服务器时间。`NtpTrustedTime.java`会创建`SntpClient`实例,调用`SntpClient.requestTime()`使用UDP协议请求网络时间,`SntpClient.java`则负责发起服务器请求,并处理返回结果。相关文件路径如下: - `frameworks/base/services/java/com/android/server/SystemServer.java`:系统服务类,用于启动管理后续的系统服务,如`NetworkTimeUpdateService`。 - `frameworks/base/services/java/com/android/server/NetworkTimeUpdateService.java`:通过`onPollNetworkTime`调用`NtpTrustedTime.forceRefresh()`获取NTP服务器时间。 - `frameworks/base/core/java/android/util/NtpTrustedTime.java`:创建`SntpClient`实例,调用`SntpClient.requestTime()`使用UDP协议请求网络时间。 - `frameworks/base/core/java/android/net/SntpClient.java`:发起服务器请求,并处理返回结果。 - `frameworks/base/core/res/res/values/config.xml`:Android系统配置`ntpServer`的文件路径 [^3]。 ### 代码示例 以下是一个简单的代码示例,展示如何使用`SntpClient`获取NTP时间: ```java import android.net.SntpClient; public class NtpTimeHelper { public static long getNtpTime() { SntpClient client = new SntpClient(); if (client.requestTime("pool.ntp.org", 10000)) { return client.getNtpTime(); } return -1; } } ``` ### 相关配置 Android系统配置`ntpServer`的文件路径为`frameworks/base/core/res/res/values/config.xml`。同时,还有几个关键的变量会影响NTP时间获取,如`mPollingIntervalMs`(当NTP时间获取成功后,再次请求NTP时间的间隔)、`mPollingIntervalShorterMs`(当NTP时间获取失败后,再次请求NTP时间的间隔)、`mTimeErrorThresholdMs`(当NTP时间和系统时间不相同时,要更新系统时间的阀值),这些变量的值是通过资源文件里读取的,配置的地址为`config.xml` [^2][^3]。 ### 监听与管理 在Android系统中,还会监听时间同步开关并进行时间设置管理。比如会进行自动同步事件监听、网络变化监听等,在`handler`中处理相关事件,在`onPollNetworkTime`方法中根据需求获取到最新时间后的具体操作 [^1]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值