Время ожидания подключения Http на Android не работает
Я пишу приложение, которое подключается к веб-сервису, и я не хочу, чтобы он слишком долго ждал, если он не может получить соединение. Поэтому я устанавливаю connectionTimeout httpparams. Но это, кажется, не имеет никакого эффекта.
Чтобы протестировать, я временно поворачиваю свою WLAN. Приложение пытается подключиться в течение некоторого времени (путь больше, чем 3 секунды, который я хочу), а затем генерирует исключение UnknownHostException.
Вот мой код:
try{
HttpClient httpclient = new DefaultHttpClient();
HttpParams params = httpclient.getParams();
HttpConnectionParams.setConnectionTimeout(params, 3000);
HttpConnectionParams.setSoTimeout(params, 3000);
httppost = new HttpPost(URL);
StringEntity se = new StringEntity(envelope,HTTP.UTF_8);
httppost.setEntity(se);
//Code stops here until UnknownHostException is thrown.
BasicHttpResponse httpResponse = (BasicHttpResponse) httpclient.execute(httppost);
HttpEntity entity = httpResponse.getEntity();
return entity;
}catch (Exception e){
e.printStackTrace();
}
У кого-нибудь есть идеи, что я пропустил?
Ответы
Ответ 1
Попробуйте сделать это следующим образом:
HttpPost httpPost = new HttpPost(url);
StringEntity se = new StringEntity(envelope,HTTP.UTF_8);
httpPost.setEntity(se);
HttpParams httpParameters = new BasicHttpParams();
// Set the timeout in milliseconds until a connection is established.
int timeoutConnection = 3000;
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
// Set the default socket timeout (SO_TIMEOUT)
// in milliseconds which is the timeout for waiting for data.
int timeoutSocket = 3000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters);
BasicHttpResponse httpResponse = (BasicHttpResponse) httpClient.execute(httpPost);
HttpEntity entity = httpResponse.getEntity();
return entity;
Затем вы можете поймать возможный ConnectTimeoutException
.
Ответ 2
С отмеченным решением я все равно получаю сообщение UnknownHostException через 30 секунд. В этом случае устройство подключается к Wi-Fi-маршрутизатору, но нет доступа в Интернет.
Принятый подход состоял в том, чтобы запустить AsyncTask, который просто попытается решить имя хоста. Блокирующий вызов проверяет каждые 250 мс, чтобы убедиться, что это удалось, и через 4 секунды он отменит задачу и вернется.
Это то, что я сделал для его решения:
private boolean dnsOkay = false;
private static final int DNS_SLEEP_WAIT = 250;
private synchronized boolean resolveDns(){
RemoteDnsCheck check = new RemoteDnsCheck();
check.execute();
try {
int timeSlept = 0;
while(!dnsOkay && timeSlept<4000){
//Log.d("RemoteDnsCheck", "sleeping");
Thread.sleep(DNS_SLEEP_WAIT);
timeSlept+=DNS_SLEEP_WAIT;
//Log.d("RemoteDnsCheck", "slept");
}
} catch (InterruptedException e) {
}
if(!dnsOkay){
Log.d("resolveDns", "cancelling");
check.cancel(true);
Log.d("resolveDns", "cancelled");
}
return dnsOkay;
}
private class RemoteDnsCheck extends AsyncTask<Void, Void, Void>{
@Override
protected Void doInBackground(Void... params) {
try {
Log.d("RemoteDnsCheck", "starting");
dnsOkay = false;
InetAddress addr = InetAddress.getByName(baseServiceURL);
if(addr!=null){
Log.d("RemoteDnsCheck", "got addr");
dnsOkay = true;
}
} catch (UnknownHostException e) {
Log.d("RemoteDnsCheck", "UnknownHostException");
}
return null;
}
}
Затем, в любое время, когда я хочу сделать веб-вызов, это вызывается в начале функции:
if(!resolveDns()){
return null;
}
Ответ 3
Смотрите: fooobar.com/questions/41825/...
Проблема может быть в HTTP-клиенте Apache. См. HTTPCLIENT-1098. Исправлено в 4.1.2.
Исключение тайм-аута пытается отменить DNS-IP для целей ведения журнала. Это занимает дополнительное время, пока исключение не будет действительно запущено.
Ответ 4
Этот метод работает для меня:
AndroidHttpTransport androidHttpTransport = new AndroidHttpTransport( endpoint, 3000) ;
Ответ 5
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
// Set the default socket timeout (SO_TIMEOUT)