Тайм-аут соединения Http на Android не работает - PullRequest
42 голосов
/ 19 июня 2010

Я пишу приложение, которое подключается к веб-сервису, и я не хочу, чтобы оно слишком долго ждало, если не может установить соединение.Поэтому я устанавливаю 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();
}

У кого-нибудь есть идеиЯ пропустил?

Ответы [ 5 ]

74 голосов
/ 19 июня 2010

Попробуйте сделать так:

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.

9 голосов
/ 04 июня 2013

С помеченным решением я все еще получаю 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 голосов
/ 17 ноября 2013

См .: https://stackoverflow.com/a/20031077/2609238

Возможно, проблема в HTTP-клиенте Apache.Смотри HTTPCLIENT-1098.Исправлено в 4.1.2.

Исключение тайм-аута пытается изменить DNS IP в целях ведения журнала.Это займет дополнительное время, пока исключение не будет фактически запущено.

1 голос
/ 05 сентября 2011

Этот метод работает для меня:

AndroidHttpTransport androidHttpTransport = new AndroidHttpTransport( endpoint, 3000) ;
0 голосов
/ 22 марта 2013
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
// Set the default socket timeout (SO_TIMEOUT)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...