guy*_*y_m 11 java android httpurlconnection android-volley
所以我Google Volley用于HTTP请求,基本上使用Java的是HttpURLConnection.
根据我的测试,问题是:
当达到'读'超时时HttpURLConnection,在连接关闭之前执行静默重试并抛出相关的异常(SocketTimeoutException).
请注意:
- 我在使用HTTP POST请求时注意到此错误.
- 'read'超时与'connect'超时不同.
- 如果未设置'read'超时(通过调用connection.setReadTimeout(int)设置)(0),或设置为大于该值connection.setConnectTimeout(int),则不会发生此错误.
- 这个问题已经在这里讨论了,但是我没有找到任何令人满意的解决方案.
- 这里可以找到一个有点相关的问题,但我不确定它是否相关(是吗?)
更多背景
我的应用程序用于付钱,所以不重试请求是至关重要的(是的,我知道它可以由服务器处理,我希望我的客户端"正确"无论如何).
设置'read'超时时,如果服务器连接已建立,但服务器在应答之前等待/ sleeps/delays-response'超时'时间(从而引发'read'异常,而不是'connect'异常) ,在引发异常之前发送另一个(静默)请求,导致2个类似的请求,这是不可接受的.
我在找什么样的解决方案?
好吧,一个能很好地解决这个问题/错误的问题,就像这里解释的解决方案一样(但我再说一遍,我认为在这种情况下它是无关紧要的).
此外,我希望保持原始流程不变,这意味着不要强制连接关闭或类似的东西.
我现在要做的是,将'read'超时设置为'connection'超时的两倍(它们同时开始计数),以确保首先引发'connection'异常.我还将尝试在服务器端克服此问题.问题是,这个"读取"超时是有原因的,我当前的实现实际上只是忽略它,并且只处理"连接"超时.
编辑
该Volley图书馆的RetryPolicy还没有在这个问题上的影响,因为这是一个静默重试.我在图书馆里看起来尽可能深.到处记录/断点,取消了重试的调用.我怎么知道它是99.99%的HttpURLConnection问题.
这个糟糕的决定是由开发人员在2006年做出的.这是一个很好的引用来自某人从java的角度解释整个情况:
"正如你可能猜到的那样,这是一个错误(http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6382788).当然,不是重试机制,这只是废话.这个错误就是它也是发生了一个POST(默认情况下,根据HTTP RFC不是幂等的.)但是不用担心,Bill很久以前就修复了这个bug.比尔通过引入切换来修复它.Bill了解了向后兼容性.Bill认为它更好默认情况下,将开关保持为"打开",因为这样可以使其向后兼容.比尔微笑.他已经可以看到全球各地惊讶的开发人员面对此问题了.请不要像比尔?
资源
那么建议的解决方案是:
System.setProperty("sun.net.http.retryPost", "false")
Run Code Online (Sandbox Code Playgroud)
但是我们不能在android上做到这一点!唯一剩下的解决方案是:
httpURLConnection.setChunkedStreamingMode(0);
Run Code Online (Sandbox Code Playgroud)
这似乎有效,但从请求时间的perspektive不是很有效.
编辑:我无法使用此实现,所以我寻找一个替代库.我发现自Android 4.4以来HttpUrlConnection的实现使用了OkHttp.由于OkHttp是opensource,我可以搜索他们是否也有静默重试问题.他们有问题,并在2016年4月修复它.CommonsWare(一个真正的Android专家)解释说,每个制造商都可以决定他们可以使用哪种实现.因此,必须有很多设备在POST请求上进行静默重试,作为开发人员,我们只能尝试一些workarrounds.
我的解决方案是更改库
编辑2:为您提供最终答案: 您现在可以使用OkHttp作为Volley的传输层,只需最少的代码.