Intereting Posts
Webview crash NullPointerException android.webkit.WebViewDatabase.initDatabase (WebViewDatabase.java:234) Как я могу получить функцию масштабирования для изображений? Постоянный значок службы в панели уведомлений Как мы можем обрабатывать разные типы ответов с помощью Retrofit 2? Что представляет собой образ системы MIPS в Android SDK manager? Скрыть кнопку микрофона Виртуальная клавиатура Android Уведомление Не показывать Задайте текст для целочисленного значения Просмотр файлов postscript на android Как рассчитать расстояние между двумя точками, используя их долготу и значение широты Android – Почему ConnectivityManager.isActiveNetworkMetered всегда возвращает true (даже если на Wi-Fi) Как интегрировать функцию «Как» и «Комментировать» с помощью Android Facebook SDK? Эта активность уже имеет панель действий, предоставляемую декором окна Как можно управлять вариантами вывода с помощью Android Gradle Plugin 3.0.0+? Android DrawBitmap Производительность для множества растровых изображений?

Почему значение тайм-аута не соблюдается андроидом HttpURLConnection?

У меня есть следующий код:

try { URL url = new URL("http://site-to-test.com/nonexistingpage.html"); HttpURLConnection urlc = (HttpURLConnection) url.openConnection(); urlc.setRequestProperty("User-Agent", CoreProtocolPNames.USER_AGENT); urlc.setRequestProperty("Connection", "close"); urlc.setConnectTimeout(500); // timeout is in milliseconds urlc.connect(); if (urlc.getResponseCode() == 404) { // Server was reachable Log.i(TAG, "Server is reachable"); } } catch (MalformedURLException mue) { Log.e(TAG, "MalformedURLException: " + mue.getMessage()); } catch (IOException e) { Log.e(TAG, "IOException: " + e.getMessage()); } 

Когда домен, доступный для сайта, недоступен через текущую сеть, этот код блокируется примерно на 30-40 секунд до получения IOException . И я специально установил значение тайм-аута в 500 мс. Что мне здесь не хватает? Не должен ли этот блок заканчиваться через полсекунды, независимо от состояния сети и доступности сайта?

Solutions Collecting From Web of "Почему значение тайм-аута не соблюдается андроидом HttpURLConnection?"

Похоже, что Java URLConnection не дает отказоустойчивого таймаута при чтении

Решение, как объясняет статья, использовать отдельный поток для синхронизации и отключить HttpURLConnection вручную, как только поток таймера будет выполнен.

После глубоких исследований и много трасс я обнаружил, что лучший способ реализовать таймер для AsyncTask (или Service, объект, который вы использовали для выполнения фоновой работы), от класса HTTP-соединения, так как иногда при отключении HTTP-соединения это Не прерывает веб-вызов, я реализовал этот класс, который будет использоваться, когда вам понадобится проверка таймаута для вашего HTTP-соединения

 public abstract class AsyncTaskWithTimer<Params, Progress, Result> extends AsyncTask<Params, Progress, Result> { private static final int HTTP_REQUEST_TIMEOUT = 30000; @Override protected Result doInBackground(Params... params) { createTimeoutListener(); return doInBackgroundImpl(params); } private void createTimeoutListener() { Thread timeout = new Thread() { public void run() { Looper.prepare(); final Handler handler = new Handler(); handler.postDelayed(new Runnable() { @Override public void run() { if (AsyncTaskWithTimer.this != null && AsyncTaskWithTimer.this.getStatus() != Status.FINISHED) AsyncTaskWithTimer.this.cancel(true); handler.removeCallbacks(this); Looper.myLooper().quit(); } }, HTTP_REQUEST_TIMEOUT); Looper.loop(); } }; timeout.start(); } abstract protected Result doInBackgroundImpl(Params... params); } 

Образец для этого

 public class AsyncTaskWithTimerSample extends AsyncTaskWithTimer<Void, Void, Void> { @Override protected void onCancelled(Void void) { Log.d(TAG, "Async Task onCancelled With Result"); super.onCancelled(result); } @Override protected void onCancelled() { Log.d(TAG, "Async Task onCancelled"); super.onCancelled(); } @Override protected Void doInBackgroundImpl(Void... params) { // Do background work return null; }; }