Android系统用于网络时间更新的最重要的类NetworkTimeUpdateService,在SystemServer中初始化调用,NetworkTimeUpdateService类中的依次进行构造函数和systemRunning方法进行初始化工作,获取时间的机制,在规定连接次数里面采用每隔一分钟获取NTP时间一次,超过连接次数采用240h周期更新一次NTP时间;
构造函数
public NetworkTimeUpdateService(Context context) {
mContext = context;
mTime = NtpTrustedTime.getInstance(context);
mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
Intent pollIntent = new Intent(ACTION_POLL, null);
mPendingPollIntent = PendingIntent.getBroadcast(mContext, POLL_REQUEST, pollIntent, 0);
mPollingIntervalMs = mContext.getResources().getInteger(
com.android.internal.R.integer.config_ntpPollingInterval);
mPollingIntervalShorterMs = mContext.getResources().getInteger(
com.android.internal.R.integer.config_ntpPollingIntervalShorter);
mTryAgainTimesMax = mContext.getResources().getInteger(
com.android.internal.R.integer.config_ntpRetry);
mTimeErrorThresholdMs = mContext.getResources().getInteger(
com.android.internal.R.integer.config_ntpThreshold);
}
mTime获取实际请求NTP时间的类,后面分析怎么获取发热NTP时间;
mPollingIntervalMs更新NTP时间的长周期,默认值来自/framework/base/core/res/value/config.xml配置,默认240h;
mPollingIntervalShorterMs更新NTP时间的短周期,默认值来自/framework/base/core/res/value/config.xml配置,默认1min;
mTryAgainTimesMax尝试连接获取NTP时间的次数,默认值来自/framework/base/core/res/value/config.xml配置,默认3次;
mTimeErrorThresholdMs获取NTP时间连接的超时时间,默认值来自/framework/base/core/res/value/config.xml配置,默认20s;
systemRunning函数
public void systemRunning() {
registerForTelephonyIntents();
registerForAlarms();
registerForConnectivityIntents();
HandlerThread thread = new HandlerThread(TAG);
thread.start();
mHandler = new MyHandler(thread.getLooper());
// Check the network time on the new thread
mHandler.obtainMessage(EVENT_POLL_NETWORK_TIME).sendToTarget();
mSettingsObserver = new SettingsObserver(mHandler, EVENT_AUTO_TIME_CHANGED);
mSettingsObserver.observe(mContext);
mNTPServerObserver = new NTPServerObserver(mHandler, EVENT_NTPSERVER_CHANGED);
mNTPServerObserver.observe(mContext);
}
registerForTelephonyIntents注册NITZ时间更新广播;
registerForAlarms注册alarm定时器intent;
registerForConnectivityIntents注册网络改变的广播;
mSettingsObserver系统设置中修改时区更新NTP时间;
mNTPServerObserver系统设置修改NTP服务器地址更新NTP时间;
mHandler.obtainMessage(EVENT_POLL_NETWORK_TIME).sendToTarget发送EVENT_POLL_NETWORK_TIME消息开始,调用
onPollNetworkTime方法更新NTP时间;
private void onPollNetworkTime(int event) {
// If Automatic time is not set, don't bother.
if (!isAutomaticTimeRequested()) return;
final long refTime = SystemClock.elapsedRealtime();
// If NITZ time was received less than mPollingIntervalMs time ago,
// no need to sync to NTP.
if (mNitzTimeSetTime != NOT_SET && refTime - mNitzTimeSetTime < mPollingIntervalMs) {
resetAlarm(mPollingIntervalMs);
return;
}
final long currentTime = System.currentTimeMillis();
if (DBG) Log.d(TAG, "System time = " + currentTime);
// Get the NTP time
if (mLastNtpFetchTime == NOT_SET || refTime >= mLastNtpFetchTime + mPollingIntervalMs
|| event == EVENT_AUTO_TIME_CHANGED || event == EVENT_NETWORK_CONNECTED) {
if (DBG) Log.d(TAG, "Before Ntp fetch");
// force refresh NTP cache when outdated
if (mTime.getCacheAge() >= mPollingIntervalMs || event == EVENT_NETWORK_CONNECTED) {
mTime.forceRefresh(); //获取ntp时间
}
// only update when NTP time is fresh
if (mTime.getCacheAge() < mPollingIntervalMs) {
final long ntp = mTime.currentTimeMillis();
mTryAgainCounter = 0;
// If the clock is more than N seconds off or this is the first time it's been
// fetched since boot, set the current time.
if (Math.abs(ntp - currentTime) > mTimeErrorThresholdMs
|| mLastNtpFetchTime == NOT_SET) {
// Set the system time
if (DBG && mLastNtpFetchTime == NOT_SET
&& Math.abs(ntp - currentTime) <= mTimeErrorThresholdMs) {
Log.d(TAG, "For initial setup, rtc = " + currentTime);
}
if (DBG) Log.d(TAG, "Ntp time to be set = " + ntp);
// Make sure we don't overflow, since it's going to be converted to an int
if (ntp / 1000 < Integer.MAX_VALUE) {
SystemClock.setCurrentTimeMillis(ntp); //设置系统时间
}
} else {
if (DBG) Log.d(TAG, "Ntp time is close enough = " + ntp);
}
mLastNtpFetchTime = SystemClock.elapsedRealtime();
} else {
// Try again shortly
mTryAgainCounter++;
if (mTryAgainTimesMax < 0 || mTryAgainCounter <= mTryAgainTimesMax) { //设置短周期更新
resetAlarm(mPollingIntervalShorterMs);
} else {
// Try much later
mTryAgainCounter = 0;
resetAlarm(mPollingIntervalMs); //设置长时间更新周期
}
return;
}
}
resetAlarm(mPollingIntervalMs);
}
mTime(NtpTrustedTime)为更新NTP时间的实现类,此类中实现NTP时间获取的具体逻辑,可以配置更新服务器的地址,默认地址为
framework/base/core/res/value/config.xml配置的config_ntpServer参数值;
public synchronized boolean refreshTime() {
hasForceRefresh = true;
if (LOGD) Log.d(TAG, "refreshtime() from cache miss in thread");
final SntpClient client = new SntpClient();
String myServer;
final String[] NTP_HOST = { //配置NTP服务器地址
"192.168.58.74", "202.120.2.101",
"pool.ntp.org","94.23.220.143","195.34.187.132","192.168.58.74", "202.120.2.101",
"pool.ntp.org","94.23.220.143","195.34.187.132","192.168.58.74", "202.120.2.101",
"pool.ntp.org","94.23.220.143","195.34.187.132"};
for(int i=0;i < NTP_HOST.length+2;i++){
if(i==0){
myServer = mServer;
} else if (i==1) {
myServer = mServer2;
}else {
myServer = NTP_HOST[i-2];
}
Log.i(TAG, "refreshtime() from "+myServer);
if (client.requestTime(myServer, (int) mTimeout)){
mHasCache = true;
mCachedNtpTime = client.getNtpTime(); //获取ntp时间
mCachedNtpElapsedRealtime = client.getNtpTimeReference();
mCachedNtpCertainty = client.getRoundTripTime() / 2;
hasForceRefresh = false;
Log.i(TAG, "refreshtime() success myServer = "+ myServer);
return true;
}
}
Log.i(TAG, "refreshtime() fail");
hasForceRefresh = false;
return false;
}