问题
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.
回答1:
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.
回答2:
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:
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)
{
}
}
来源:https://stackoverflow.com/questions/20104404/android-kitkat-httpurlconnection-disconnect-asynctask