У меня есть приложение для Android, которое выполняет HTTP-запросы на получение в фоновом режиме.Я дам некоторые детали того, как это выполняется в ближайшее время.Сначала я остановлюсь на описании проблемы.
Я заметил в отладчике, что OkHttp ConnectionPool
s складывается в окне Threads
в Android Studio.Это касается меня, так как кажется, что это указывает на утечку ресурсов, и со временем они будут увеличиваться бесконечно (кажется).
Моя главная проблема заключается в том, что я понятия не имею, почему это происходит.Я почти уверен, что это моя вина, но я не знаю, что искать.Итак, мой общий вопрос:
«Что может вызвать создание нового пула при каждом выполнении HTTP-запроса?»
Во-первых, вот код, который я использую для выполнения запроса get.Обратите внимание, что это упрощено, но я бегу с этим точным кодом и вижу проблему.
private TestResult test() {
final long startTime = SystemClock.elapsedRealtime();
final String server = "connectivitycheck.gstatic.com";
URL url;
try {
url = new URL("http", SOME_PATH);
} catch (MalformedURLException e) {
// We shouldn't get here since the url is well known
return new TestResult(
"failed to generate url " + e,
SystemClock.elapsedRealtime() - startTime
);
}
HttpURLConnection urlConnection = null;
int httpResponseCode;
try {
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setInstanceFollowRedirects(false);
urlConnection.setConnectTimeout(SOCKET_TIMEOUT_MS);
urlConnection.setReadTimeout(SOCKET_TIMEOUT_MS);
urlConnection.setUseCaches(false);
InputStream is = urlConnection.getInputStream();
httpResponseCode = urlConnection.getResponseCode();
is.close();
} catch (IOException e) {
return new TestResult(
e,
SystemClock.elapsedRealtime() - startTime
);
} finally {
if (urlConnection != null)
urlConnection.disconnect();
}
if (httpResponseCode != HttpURLConnection.HTTP_NO_CONTENT) {
return new TestResult(
"invalid error code, expected 204 but got " + httpResponseCode,
SystemClock.elapsedRealtime() - startTime
);
}
return new TestResult(
SystemClock.elapsedRealtime() - startTime
);
}
Итак, когда этот код выполняется ...?
Во-первых, позвольте мне сказать, что я пытался запустить этот код из моей домашней активности в моем приложении (в отдельном потоке, поскольку HTTP не разрешен в основном потоке Android).Когда я это делаю, все в порядке.Я могу сделать несколько запросов и никогда не видеть более одного пула.
Ситуация, в которой я запускаю код и вижу проблемы, выглядит следующим образом:
- У меня есть фон
Service
- В этой службе я запускаю новый
Thread
В этой теме я создаю ExecutorService
:
ExecutorService executorService = Executors.newCachedThreadPool();
CompletionService<FutureResult> completionService = new ExecutorCompletionService<>(executorService);
Используя это ExecutorService
, я отправляю вызываемую задачу, которая запускает мой метод test
(см. Выше).
Обратите внимание, что все это может показаться запутанным, но во всем этом есть смысл.Во-первых, ExecutorService
будет выполнять много других задач, помимо запуска метода test
.
Я хорошо выглядел для висящих ссылок, которые каким-то образом могли поддерживать живые базовые ресурсы HTTP, ноЯ ничего не вижу.
Кто-нибудь с хорошим знанием OkHttp знает, почему это может произойти?Я надеюсь, что некоторые идеи помогут мне раскрыть проблему.