Android KitKat HttpURLConnection отключить AsyncTask

В своем приложении я загружаю файл, используя HttpURLConnection в AsyncTask. Если файл загружается слишком долго, я хочу отменить его; и я делаю это, закрывая поток и вызывая disconnect() на объект HttpURLConnection. Код годами безупречно работал в Android. Однако теперь, когда KitKat вышел, возникли проблемы. В частности, сам вызов disconnect() занимает несколько секунд или больше. В устройствах до KitKat это занимало миллисекунду или меньше. Что действительно странно, так это то, что когда я выполняю вызов разъединения в отдельном потоке, он снова работает очень быстро. Так что это должно быть проблемой с вызовом его в методе AsyncTask doInBackground. Следует отметить, что у моего AsyncTask действительно есть вызов Looper.prepare().

Кто-нибудь знает, в чем разница между KitKat и другими версиями Android? Я просмотрел списки изменений и не нашел ничего, связанного с этой проблемой.


person Chris Feist    schedule 20.11.2013    source источник
comment
Имея ту же проблему   -  person Nami    schedule 21.11.2013
comment
Я вижу аналогичную проблему; Я провел некоторое расследование, и это изменение в способе закрытия потоков. Подробнее я рассказал здесь - К сожалению, у меня пока нет исправления.   -  person Adam S    schedule 01.12.2013
comment
Тот же результат, а также отключение в отдельном потоке делает для меня такую ​​​​же задержку.   -  person Pointer Null    schedule 19.03.2014


Ответы (3)


Кажется, что Kitkat использует okhttp вместо предыдущей реализации HTTPConnection, или, по крайней мере, так обстоит дело на устройствах Nexus с официальным обновлением.

person debaj    schedule 04.12.2013
comment
Как вы это определили? Я просмотрел исходный код и вижу, что библиотеки okhttp были в источнике начиная с 4.2. - person Chris Feist; 04.12.2013
comment
https://android.googlesource.com/platform/external/okhttp/+log/ Изменения, реализованные в 2231db3, не существуют в Android 4.3 (независимо от того, что говорят теги); они существуют в Android 4.4. - person Adam S; 05.12.2013
comment
Ах хорошо. Мне все еще любопытно, почему поведение в AsyncTask будет отличаться от поведения в отдельном потоке. - person Chris Feist; 09.12.2013

Это может быть связано с постоянными подключениями и попыткой HttpURLConnection повторно использовать одно и то же HTTP-соединение, поэтому при закрытии connection или InputStream, он пытается использовать все оставшиеся данные, читая их и отбрасывая. Затем то же HTTP-соединение готово для следующей команды.

Кажется, в KitKat есть какая-то новая реализация, которая делает вещи другими и вызывает проблемы.

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

я пытался позвонить

HttpURLConnection con;
con.setRequestProperty("Connection", "close");

но это не имело значения.

Однако я попытался использовать тот же код с DefaultHttpClient. и звоню

HttpGet get = new HttpGet(uri);
get.addHeader("Connection", "close");

затем, наконец, быстрое закрытие InputStream соединения, что я доказал в отладчике, войдя в ConnectionReuseStrategy.keepAlive и увидев, что сервер вернул Connection:close, а DefaultHttpClient не пытался повторно использовать соединение и читать до конца.

Таким образом, вы можете использовать DefaultHttpClient или найти способ заставить HttpURLConnection просто закрыть соединение без чтения остальных.

person Pointer Null    schedule 19.03.2014

Почему бы вам не попробовать использовать http-соединение apache lib

что-то вроде этого внутри вашей асинхронной задачи

    HttpClient httpclient = new DefaultHttpClient();
    HttpPost httppost = new HttpPost("http://server.com");
    HttpResponse response = httpclient.execute(httppost);
    if(response!=null)
    {
        final  String responseBody =EntityUtils.toString(response.getEntity());
        if (responseBody != null) 
        {  



        }

    }
person kmarin    schedule 18.12.2013
comment
Пару лет назад это молча устарело, и Google рекомендует использовать HttpURLConnection. См. этот сообщение в блоге. - person Chris Feist; 18.12.2013
comment
Я знаю, что есть несколько портов последней версии Apache для Android, но я чувствую, что сырая Java-программа должна работать. - person Chris Feist; 18.12.2013
comment
Привет, Крис, спасибо за информацию, я знаю, что он не поддерживается Google, хотя отлично работает, обычно я предпочитаю использовать библиотеку apache, поскольку она быстрее, чем стандартное HTTP-соединение Java. также нет необходимости в части кода readline. веб-страница возвращается прямо как строка. в моем случае это работает отлично, я очень рекомендую его. - person kmarin; 19.12.2013
comment
Я тестировал, и использование HttpClient и закрытие ответа InputStream приводит к такой же большой задержке (15 секунд) на моем устройстве. borg666: правильно отформатируйте пример кода! - person Pointer Null; 19.03.2014
comment
@PointerNull, мы не принимаем здесь заказы, в следующий раз обязательно попросите об этом, вы не в пабе. - person kmarin; 20.03.2014
comment
@borg666: мои извинения, конечно, я был напряжен из-за сложного программирования;) - person Pointer Null; 21.03.2014