我试图从网络获取当前时间,以便我的应用程序可以在文本视图中显示时间。但是,时间有时只会归还给我,我无法弄清楚原因。
我使用AsyncTask在单独的线程上联系time-a.nist.gov,然后用结果更新我的文本视图。这是第一次我的应用程序启动时有效,有时是第二次,但之后我注意到我一直卡在这条线上:
TimeInfo timeInfo = timeClient.getTime(inetAddress);
我没有得到异常,以下日志语句都没有通过,没有。它只是挂起,我的文本视图是空白的。这是我的代码:
public static final String TIME_SERVER = "time-a.nist.gov";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_rtc_test);
networkTimeTextView = (TextView) findViewById(R.id.tv_current_network_time);
new GetTimeFromNetwork().execute();
}
public class GetTimeFromNetwork extends AsyncTask<Date, Void, Date> {
@Override
protected Date doInBackground(Date... params) {
Log.i("RTCTestActivity", "Getting time...");
try {
NTPUDPClient timeClient = new NTPUDPClient();
Log.i("RTCTestActivity", "Getting inet address..");
InetAddress inetAddress = InetAddress.getByName(TIME_SERVER);
Log.i("RTCTestActivity", "Getting time info..");
TimeInfo timeInfo = timeClient.getTime(inetAddress);
Log.i("RTCTestActivity", "Got time info");
long networkTimeLong = timeInfo.getMessage().getTransmitTimeStamp().getTime();
Date networkTimeDate = new Date(networkTimeLong);
Log.i("time", "Time from " + TIME_SERVER + ": " + networkTimeDate);
return networkTimeDate;
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Date result) {
super.onPostExecute(result);
if (result == null) {
Toast.makeText(RTCTestActivity.this, "Not connected to internet", Toast.LENGTH_SHORT).show();
return;
}
String networkTimeString = "Network time: " + timeFormat.format(result);
Log.v("RTCTestActivity", "Network time formatted: " + networkTimeString);
networkTimeTextView.setText(networkTimeString);
}
}
再一次,它将获取一次或两次网络时间(有时甚至完全没有),并且每次在网络时间之后只停留在上面一行,就像没有打印出来一样#34;得到时间信息&#34;甚至是一个例外。有什么想法吗?
答案 0 :(得分:0)
我找到了解决方案。看来我的连接超时,然后我的程序不知道如何处理它。我通过向NTPUDPClient
添加DefaultTimeout然后将我的连接请求放入循环来解决了这个问题。如果超时,我会尝试重新连接。
修复程序位于doInBackground()。
/** Async task to get time from the network. */
private class GetTimeFromNetwork extends AsyncTask<String, Void, String> {
@Override
protected void onPreExecute() {
super.onPreExecute();
// Inform user that we are connecting to the network.
// Only do this on create, or else it will look strange to the user.
if (!broadcastingNetworkTime) setNetworkTime("Connecting...");
}
@Override
protected String doInBackground(String... params) {
Log.i("RTCTestActivity", "Connecting to network...");
// Client for getting time from network.
NTPUDPClient timeClient = new NTPUDPClient();
timeClient.setDefaultTimeout(1000);
// Connect to network. Try again on timeout (max 6).
for (int retries = 7; retries >= 0; retries--) {
try {
// Try connecting to network to get time. May timeout.
InetAddress inetAddress = InetAddress.getByName(TIME_SERVER);
TimeInfo timeInfo = timeClient.getTime(inetAddress);
long networkTimeLong = timeInfo.getMessage().getTransmitTimeStamp().getTime();
// Convert long to Date, and Date to String. Log results.
Date networkTimeDate = new Date(networkTimeLong);
String networkTimeString = networkTimeFormat.format(networkTimeDate);
Log.i("Time", "Time from " + TIME_SERVER + ": " + networkTimeDate);
// Return resulting time as a String.
return networkTimeString;
} catch (IOException e) {
// Max of 6 retries.
Log.i("RTCTestActivity", "Unable to connect. Retries left: " + (retries-1));
}
}
// Unable to connect to network.
return null;
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if (result == null) {
// Not found. Disconnected from internet or too many timeouts.
Toast.makeText(RTCTestActivity.this, "Unable to get network time.", Toast.LENGTH_SHORT).show();
setNetworkTime("Unavailable");
return;
}
// Display resulting time in text view.
setNetworkTime(result);
}
} // end async task
我在某些时候也将我的返回类型更改为String,但这不应该造成太大的差别。这个解决方案对我来说始终如一,而且我还没有遇到任何问题。