Android UnknownHostException: есть ли способ установить время ожидания? - PullRequest
28 голосов
/ 09 марта 2012

Когда я подключаюсь к своему веб-сервису для получения данных, телефон иногда отключается, портится DNS и т. Д. Затем я получаю UnknownHostException, что совершенно нормально.

Что я хочу сделать, это установить тайм-аут при поиске hostName здесь:

 response = httpclient.execute(httpget);

Я уже установил:

HttpConnectionParams.setConnectionTimeout(httpParameters,timeoutConnection);
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);

но, похоже, они не подаются на HostLookUp. Есть ли способ установить время ожидания при поиске хоста?

Редактировать
Я только что обнаружил, что пользователь не может изменить время ожидания nslookup в этом сообщении в списке рассылки hc-dev .

Мне нужно будет вручную сгенерировать исключение тайм-аута от таймера в этой точке.

Ответы [ 12 ]

2 голосов
/ 25 июля 2015

Прежде всего HttpParams httpParams = new BasicHttpParams () запрещен, используйте этот HttpURLConnection conn = (HttpURLConnection) url.openConnection ();

когда размер ваших параметров больше 2 МБ, сервер дает время ожидания.

Проверьте размер ваших параметров и дайте мне знать.

0 голосов
/ 17 июня 2015

Для меня тайм-аут не использовался, если мы потеряли соединение (для проверки: выключить WiFi). Поэтому я написал метод, который пытается загрузить файл до X раз, ожидая Y миллисекунд между каждой попыткой:

public static byte[] getByteArrayFromURL(String url, int maxTries, int intervalBetweenTries) throws IOException {

    try {

        return Utils.getByteArrayFromURL(url);
    }
    catch(FileNotFoundException e) { throw e; }
    catch(IOException e) {

        if(maxTries > 0) {

            try {
                Thread.sleep(intervalBetweenTries);
                return getByteArrayFromURL(url, maxTries - 1, intervalBetweenTries);
            }
            catch (InterruptedException e1) {

                return getByteArrayFromURL(url, maxTries -1, intervalBetweenTries);
            }
        }
        else {

            throw e;
        }
    }
}

Вот метод, который загружает файл и генерирует исключение UnknownHostException:

public static byte[] getByteArrayFromURL(String urlString) throws IOException {

    ByteArrayOutputStream out = new ByteArrayOutputStream();
    InputStream in = null;
    try {

        in = new URL(urlString).openStream();
        byte[] byteChunk = new byte[BUFFER_SIZE];
        int n;

        while ((n = in.read(byteChunk)) > 0) {
            out.write(byteChunk, 0, n);
        }
    }
    finally {
        if (in != null) {
            try { in.close(); }
            catch (IOException e) { e.printStackTrace(); }
        }
    }

    return out.toByteArray();
}

Теперь, если файл, который вы хотите загрузить, не существует, метод немедленно завершится сбоем, в противном случае, если будет сгенерировано исключение IOException (например, UnknownHostException), он будет повторять до «maxTries», ожидая «intervalBetweenTries» между каждой попыткой.

Конечно, вы должны использовать это асинхронно.

0 голосов
/ 23 июля 2015

Попробуйте это, может быть, это будет полезно для вас.

final HttpParams httpParams = new BasicHttpParams()


HttpConnectionParams.setConnectionTimeout(httpParams, 1000)


HttpConnectionParams.setSoTimeout(httpParams, 30000) 

HttpClient hc = new DefaultHttpClient(httpParams)

try
 {


 HttpGet get = new HttpGet("http://www.google.com")

  HttpResponse response = hc.execute(get)

  take your response now.

}

0 голосов
/ 16 января 2014

Будет лучше, если вы будете использовать многопоточность для сетевых операций, тогда вы можете указать время ожидания извне. Я использовал этот метод для решения проблемы, когда определение времени ожидания не работало.

В этом методе коды связи после записи записываются в обработчике. Мы можем запустить этот обработчик, отправив сообщение (мы также можем передавать данные через сообщения). Инициирующие операторы записываются в таймере обратного отсчета и после кодов связи в потоке. И в обработчике записывается необходимый код, чтобы отключить больше запуск (путем назначения нового пустого обработчика для объекта), чтобы сработал только один из них.

Если вам нравится эта логика и требуется больше объяснений. Пожалуйста, прокомментируйте ниже

0 голосов
/ 27 января 2014

Вы можете попробовать что-то вроде: -

URLConnection connection = null;
connection =  address.openConnection();
post = (HttpsURLConnection) connection;
post.setSSLSocketFactory(context.getSocketFactory()); 
post.setDoInput(true);
post.setDoOutput(true);

// Connecting to a server will fail with a SocketTimeoutException if the timeout     elapses before a connection is established
post.setConnectTimeout(Const.CONNECTION_TIMEOUT_DELAY);
post.setRequestMethod("POST");  // throws ProtocolException


post.setRequestProperty("soapaction","");
post.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
post.setRequestProperty("Authorization", "Basic " +         Base64.encodeToString(strCredentials.getBytes(), Base64.NO_WRAP));
            post.setRequestProperty("Content-Length",           String.valueOf(requestEnvelope.length()));

// Чтение не удастся с SocketTimeoutException, если тайм-аут истекает до того, как данные станут доступными .. post.setReadTimeout (Const.READ_TIMEOUT_DELAY);

0 голосов
/ 07 января 2014

Я считаю, что библиотека Volley (я бы сказал, замена AsyncTask) более проста в использовании и дает меньше ошибок.Если вы используете залп, проще управлять таймаутами.Тем не менее, что касается вашего вопроса,

  response = httpclient.execute(httpget);

с этим я предположил, что вы используете AsyncTask.В httpconnection также есть опция settimeout(), но она не работает должным образом из-за проблем с DNS.Поэтому попробуйте использовать runnable() и установить время для него.Я использовал этот подход в одном из моих проектов, еще тогда, когда еще не использовал Volley.

Надеюсь, что это поможет.

0 голосов
/ 15 января 2014
DefaultHttpClient client = new DefaultHttpClient();

    HttpParams httpParameters = new BasicHttpParams();
    // Set the timeout in milliseconds until a connection is established.
    // The default value is zero, that means the timeout is not used. 
    int timeoutConnection = 30000;
    HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
//      HttpConnectionParams.setHeader("Accept", "application/json");

    // Set the default socket timeout (SO_TIMEOUT) 
    // in milliseconds which is the timeout for waiting for data.
    int timeoutSocket = 30000;
    HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);

    client.setParams(httpParameters);
0 голосов
/ 19 декабря 2013

Вы можете отправить запрос ping на ваш сервер и установить время ожидания для запроса ping.Если true, у вас есть подключение к интернету, если false, ничего не делать.Код должен выглядеть следующим образом:

public static boolean connection() throws UnknownHostException, IOException {
    String ipAddress = "94.103.35.164";
    InetAddress inet = InetAddress.getByName(ipAddress);

    if(inet.isReachable(1000)){
        return true;
    }
    else {
        return false;
    }
}

В этом примере вы можете изменить время ожидания.Я установил 1 секунду тайм-аут.

0 голосов
/ 07 ноября 2013

да, вы можете установить время ожидания, следуя этим шагам

  1. перейдите в окно затмения-> настройки-> Android-> DDMS и увеличьте время ожидания соединения ADB.
0 голосов
/ 21 октября 2013

Пожалуйста, скачайте этот Jar-файл и импортируйте его в папку lib http://grepcode.com/snapshot/repo1.maven.org/maven2/org.apache.httpcomponents/httpmime/4.2.1 и продолжайте запускать ваше приложение .. Ваш код правильный

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...