Могу ли я установить тайм-аут getaddrinfo в Android для DefaultHttpClient?

В приложении для Android я пытаюсь проверить, работает ли у пользователя рабочее интернет-соединение. Если вам интересно, в предыдущем вопросе есть какой-то фон. Обнаружение ограниченного сетевого подключения в Android?

Код в основном похож:

try { HttpParams myParams = new BasicHttpParams(); HttpConnectionParams.setConnectionTimeout(myParams, 10000); HttpConnectionParams.setSoTimeout(myParams, 10000); httpClient = new DefaultHttpClient(myParams); request = new HttpHead(url); response = httpClient.execute(request); statusCode = response.getStatusLine().getStatusCode(); if (statusCode != 200) { return false; } return true; } catch(Exception e) { return false; } 

Я могу контролировать таймауты для соединения и сокета с помощью HttpConnectionParams. Но, если мое устройство подключено к Wi-Fi, но Wi-Fi не имеет доступа в Интернет, ошибка, которую я получаю в исключении:

Libcore.io.GaiException: getaddrinfo не удалось: EAI_NODATA (Нет адреса, связанного с именем хоста)

Не удалось разрешить хост «www.example.com»: нет адреса, связанного с именем хоста

Похоже, что он был рассчитан на поиск DNS. Могу ли я контролировать тайм-аут DNS-поиска? HttpClient.execute занимает около 45 секунд, чтобы сбой с исключением, указанным выше. Я бы хотел, чтобы он сдался раньше.

Я сделал небольшую домашнюю работу, и кажется, что вы не можете настроить тайм-аут поиска DNS. Итак, я решил, что лучший подход будет заключаться в явном поиске DNS, чтобы я мог контролировать его (и, надеюсь, результат будет кэширован для ускорения следующей попытки). Так что это привело меня к простому:

 InetAddress addr = InetAddress.getByName(hostname); 

Но это также имело 45-секундный тайм-аут. Другие упоминали, что не было контроля над тайм-аутом для getByName () . Наконец, я наткнулся на простое решение, просто запустил поиск в отдельном потоке и управлял собственным таймаутом. Это сообщение в блоге показывает это довольно хорошо.

 private static boolean testDNS(String hostname) { try { DNSResolver dnsRes = new DNSResolver(hostname); Thread t = new Thread(dnsRes); t.start(); t.join(1000); InetAddress inetAddr = dnsRes.get(); return inetAddr != null; } catch(Exception e) { return false; } } private static class DNSResolver implements Runnable { private String domain; private InetAddress inetAddr; public DNSResolver(String domain) { this.domain = domain; } public void run() { try { InetAddress addr = InetAddress.getByName(domain); set(addr); } catch (UnknownHostException e) { } } public synchronized void set(InetAddress inetAddr) { this.inetAddr = inetAddr; } public synchronized InetAddress get() { return inetAddr; } } 

Используя это, я могу сначала проверить, может ли устройство разрешить имя хоста, а затем успешно ли оно выполнить тест на полную совместимость.

Intereting Posts
Событие кликов FrameLayout не срабатывает Что такое Android UiThread (UI thread) Android push-уведомление, как играть звук по умолчанию Нужна андроидная активность, чтобы подождать, пока не будет найдено местоположение GPS Android Lollipop 5.0.1 SQLiteLog Ошибка POSIX 11 Ошибка SQLite: 3850 Как я могу добавить OnClickListener в Drawable в EditText? TextView получает разрез в некоторых разрешениях Передавать данные от намерения к другому намерению Ширина кнопок в Android TableLayout Лучший способ двойного сортировки в java с помощью Collections.sort Есть ли #ifdef в Qt, чтобы определить, строим ли мы для Android? Пользовательские действия с использованием неявных намерений между приложениями Как создать программно соединение A2DP или как я могу подражать телефону Android как приемник A2DP? Как использовать и тестировать API-интерфейс Android 4.0 в эмуляторе? Изменение содержимого файла Android .aar / Преобразование в формат .zip и обратно.