有时当我在Android Gingerbread(OS 2.3.3)上运行我的应用程序时,我在logcat中有这样的警告:
java.io.IOException: No socket to write to; was a POST cached?
at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:618)
at com.voices.voices.webservice.WebService$WebServiceAsyncTask.downloadUrl(WebService.java:1705)
at com.voices.voices.webservice.WebService$WebServiceAsyncTask.doInBackground(WebService.java:1615)
at com.voices.voices.webservice.WebService$WebServiceAsyncTask.doInBackground(WebService.java:1)
at android.os.AsyncTask$2.call(AsyncTask.java:185)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
at java.lang.Thread.run(Thread.java:1019)
并且该呼叫的HttpUrlConnection失败。通常这个调用工作正常但偶尔会失败。在Android OS上运行时似乎没有这个问题> 2.3.3。
问题是为什么它失败了,我该如何解决这个问题?
以下是其他一些信息:
Webservice.java的第1705行
dataStream = new DataOutputStream(conn.getOutputStream());
错误前的行:
...
HttpURLConnection conn = null;
DataOutputStream dataStream = null;
//SETS COOKIE This should avoid the "Too many redirects issue" because It's apparently redirecting in an infinite loop because it's not maintain the user session.
CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));
if( webServiceUrl.contains("https") ){
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted( java.security.cert.X509Certificate[] certs, String authType) {
}
public void checkServerTrusted( java.security.cert.X509Certificate[] certs, String authType) {
}
}
}; // Install the all-trusting trust manager
try {
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
}
catch (Exception e) {
//L.l("TRUST MANAGER EXCEPTION");
}
}
try {
responseInputStream = null;
System.setProperty("http.keepAlive", "false");
URL url = new URL(webServiceUrl);
conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(Constants.CONNECTION_TIMEOUT_MILLISECONDS /* milliseconds */);
conn.setConnectTimeout(Constants.CONNECTION_TIMEOUT_MILLISECONDS /* milliseconds */);
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setDefaultUseCaches(false);
if( useMultipart ){
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary="+ Constants.MULTIPART_BOUNDARY);
} else {
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
}
conn.setRequestProperty("Cache-Control", "no-cache");
conn.connect();
// DATA STREAM
dataStream = new DataOutputStream(conn.getOutputStream());
...
我不确定这是否会有所帮助,但在Android的HttpURLConnectionImpl.java文件中,这是发生错误的地方
@Override
public OutputStream getOutputStream() throws IOException {
if (!doOutput) {
throw new ProtocolException("Does not support output");
}
// you can't write after you read
if (sentRequestHeaders) {
// TODO: just return 'requestBodyOut' if that's non-null?
throw new ProtocolException(
"OutputStream unavailable because request headers have already been sent!");
}
if (requestBodyOut != null) {
return requestBodyOut;
}
// they are requesting a stream to write to. This implies a POST method
if (method == GET) {
method = POST;
}
// If the request method is neither PUT or POST, then you're not writing
if (method != PUT && method != POST) {
throw new ProtocolException(method + " does not support writing");
}
int contentLength = -1;
String contentLengthString = requestHeader.get("Content-Length");
if (contentLengthString != null) {
contentLength = Integer.parseInt(contentLengthString);
}
String encoding = requestHeader.get("Transfer-Encoding");
if (chunkLength > 0 || "chunked".equalsIgnoreCase(encoding)) {
sendChunked = true;
contentLength = -1;
if (chunkLength == -1) {
chunkLength = DEFAULT_CHUNK_LENGTH;
}
}
connect();
if (socketOut == null) {
// TODO: what should we do if a cached response exists?
throw new IOException("No socket to write to; was a POST cached?");
}
因此出于某种原因,socketOut == null,非常奇怪。
如果您需要更多信息,请与我们联系。
答案 0 :(得分:0)
这可能不是最好的方式,但它对我有用。我只需要在我的httpURLConnection
上禁用缓存conn.setDefaultUseCaches(false);
conn.setUseCaches(false);
conn.setRequestProperty("Expires", "-1");
conn.setRequestProperty("Cache-Control", "no-cache");