Stopping silent retries in HttpURLConnection

2019-04-05 08:15发布

问题:

I'm using HttpURLConnection on Android KitKat to POST some data to a server. The server takes a long time to respond, and the connection is silently retrying 1 to 3 times before timing out. I don't want it to retry, since the server acts on all of the requests, resulting in Bad Things(TM).

I've tried System.setProperty("http.keepAlive", "false") before opening the connection, but that doesn't help.

回答1:

For POST calls set

httpURLConnection.setChunkedStreamingMode(0);

and this should fix the silent retries. The bug report and workaround can be found here.



回答2:

  • Implement a hard timeout yourself, and force close the HttpURLConnection by calling disconnect. This can be done from your Activity using android handler; If you use AsyncTask, you can simply call cancel or Thread.interrupt():

    new Handler().postDelayed(new Runnable() {
        public void run() {
            httpUrlConnTask.cancel(true);
        }
    }, timeout * 1000); 
    

    And in your httpUrlConnTask, call disconnect:

    if (isCancelled()) {
        urlConnection.disconnect();
        return;
    }
    

    You may have to do urlConnection in another internal child thread so you can do a while loop in asynctask monitoring for isCancelled. And a try..catch so you can close all the streams properly.

  • you already have keepAlive false, and readTimeout, consider adding connection timeout too. This will set the socket timeout.



回答3:

You need to set System.setProperty("sun.net.http.retryPost", "false")



回答4:

Android’s HTTP Clients

Prior to Froyo, HttpURLConnection had some frustrating bugs. In particular, calling close() on a readable InputStream could poison the connection pool. Work around this by disabling connection pooling:

private void disableConnectionReuseIfNecessary() {
    // HTTP connection reuse which was buggy pre-froyo
    if (Integer.parseInt(Build.VERSION.SDK) < Build.VERSION_CODES.FROYO) {
        System.setProperty("http.keepAlive", "false");
    }
}