Android KitKat HttpURLConnection disconnect AsyncT

2020-07-09 02:16发布

In my application, I download a file using an HttpURLConnection in an AsyncTask. If the file takes too long to download, then I want cancel it; and I do this by closing the stream and calling disconnect() on the HttpURLConnection object. The code has worked flawlessly for years in Android. However, now that KitKat is out, issues have popped up. Specifically, the disconnect() call itself takes several seconds or more to complete. In pre-KitKat devices, it took a millisecond or less. What is really strange is that when I perform the disconnect call on a separate thread, then it is really fast again. So it has to be an issue with calling it in the AsyncTask's doInBackground method. One thing to note is that my AsyncTask does have a Looper.prepare() call.

Does anyone know what the difference between KitKat and other Android versions is? I combed through the change lists and did not see anything related to this issue.

3条回答
孤傲高冷的网名
2楼-- · 2020-07-09 02:58

This may be related to persistent connections, and attempt of HttpURLConnection to reuse same HTTP connection, thus when closing connection or InputStream, it tries to consume all remaining data by reading them and discarding. Then same HTTP connection is ready for next command.

There seems to be some new implementation in KitKat that makes things different and causes problems.

I try to stream video data over HTTP, with occasional seeking which results in closing connection and initiating new one. Certainly I don't need fetching of video stream up to end in this case.

I tried to call

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

but it didn't make difference.

However, I tried using same code with DefaultHttpClient and calling

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

then finally closing InputStream of connection is fast, which I proved in debugger by stepping into ConnectionReuseStrategy.keepAlive and seeing that server returned Connection:close and DefaultHttpClient didn't try to reuse connection and reading till end.

So you can use DefaultHttpClient or find a way to make HttpURLConnection to just close connection without reading rest.

查看更多
干净又极端
3楼-- · 2020-07-09 03:09

Why dont you try using apache lib http connection

something like this, inside your async task

    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) 
        {  



        }

    }
查看更多
够拽才男人
4楼-- · 2020-07-09 03:11

It seems that Kitkat uses okhttp instead of the previous HTTPConnection implementation, or at least this is the case on Nexus devices with the official update.

查看更多
登录 后发表回答