Android HttpUrlConnection.openConnection第二次失败

Android HttpUrlConnection.openConnection第二次失败,android,httpurlconnection,Android,Httpurlconnection,我知道这个问题应该用System.setProperty(“http.keepAlive”、“false”)来解决;在openConnection之前,但这对我不起作用。第一次尝试此代码有效,第二次失败。即使我在不到5秒钟后尝试此请求,它也可以工作。如果我等的时间再长一点,它就会再次失败 这是我的代码: System.setProperty("http.keepAlive", "false"); HttpURLConnection conn = (HttpURLConnection)

我知道这个问题应该用System.setProperty(“http.keepAlive”、“false”)来解决;在openConnection之前,但这对我不起作用。第一次尝试此代码有效,第二次失败。即使我在不到5秒钟后尝试此请求,它也可以工作。如果我等的时间再长一点,它就会再次失败

这是我的代码:

    System.setProperty("http.keepAlive", "false");
  HttpURLConnection conn = (HttpURLConnection) mURL.openConnection();
  conn.setUseCaches(false); 
  conn.setRequestProperty("Connection","Keep-Alive"); 
  conn.setRequestProperty("User-Agent", useragent);
  conn.setConnectTimeout (30000) ; 
  conn.setDoOutput(true); 
        conn.setDoInput(true); 

  consumer.sign(conn);
  InputSource is = new InputSource(conn.getInputStream());
我在最后一行得到了异常:

java.io.IOException: Write error: I/O error during system call, Broken pipe
W/System.err( 2164):  at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.nativewrite(Native Method)
W/System.err( 2164):  at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.access$600(OpenSSLSocketImpl.java:55)
W/System.err( 2164):  at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl$SSLOutputStream.write(OpenSSLSocketImpl.java:583)
W/System.err( 2164):  at java.io.OutputStream.write(OutputStream.java:82)
W/System.err( 2164):  at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.sendRequest(HttpURLConnectionImpl.java:1332)
W/System.err( 2164):  at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.doRequestInternal(HttpURLConnectionImpl.java:1656)
W/System.err( 2164):  at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.doRequest(HttpURLConnectionImpl.java:1649)
W/System.err( 2164):  at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:1153)
W/System.err( 2164):  at org.apache.harmony.luni.internal.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:253)

有人知道这里出了什么问题吗?。谢谢

我相信您的问题在于代码的顺序。检查URLConnection JavaDocs中的那些方法。在mUrl.openConnection()上建立连接后,不应调用setRequestProperty。它可能是第一次工作,因为建立了连接,然后您正在更改的设置不会影响任何东西,直到下次尝试建立连接。请尝试改用HttpURLConnection构造函数,以便在设置属性后调用connect()。

我解决了这个问题。在这里,我给你留下代码,以防对某人有所帮助。基本上,我在Google上看到了使用HttpClient/HttpGet而不是HttpUrlConnection的趋势。所以我尝试了这些课程,一切都很好:

final HttpClient client = new DefaultHttpClient();
final HttpGet conn = new HttpGet(mURL.toString());

OAuthConsumer consumer = mOAuthManager.getPostConsumer();
consumer.sign(conn);
HttpResponse response = client.execute(conn);
InputSource is = new InputSource(response.getEntity().getContent());

HttpURLConnection
在保持连接活动时使用的连接池已断开,因此它尝试使用已被服务器关闭的连接。默认情况下,Android会在所有连接上设置KeepAlive

System.setProperty(“http.keepAlive”、“false”)
是一种对所有连接禁用KeepAlive的变通方法,这样可以避免连接池中的错误

conn.setRequestProperty(“连接”,“保持活动”)
为这个特定的连接打开KeepAlive,实质上颠倒了
System.setProperty(“http.KeepAlive”,“false”)可以

另外,我总是显式地调用
connect()
,因为它清楚地表明了连接设置的结束位置。我不确定调用此方法是否可选

System.setProperty("http.keepAlive", "false");
HttpURLConnection conn = (HttpURLConnection) mURL.openConnection();
conn.setUseCaches(false); 
conn.setRequestProperty("User-Agent", useragent);
conn.setConnectTimeout(30000);
conn.setDoOutput(true); 
conn.setDoInput(true); 
consumer.sign(conn);

conn.connect();

InputSource is = new InputSource(conn.getInputStream());

您不需要
System.setProperty(“http.keepAlive”、“false”)

您只需
conn.setRequestProperty(“连接”、“关闭”)

这解决了问题,但有效地杀死了keep alives,因此可能会使多个连接变慢(这是一个遗憾)。我在寻找harmony bug追踪器,但没有找到任何东西


@fonetik,你知道这是不是已经和harmony一起提出来了?我的意思是,这并没有多大帮助,因为另一个http相关的luni缺陷在一个多月后仍然没有分配。

这个错误已经在Android2.3版本中修复,我们知道
System.setProperty(“http.keepAlive”、“false”)
不是一个很好的解决方案,因为在移动设备上,每次创建连接的成本都很高。

当我尝试打开https连接时,它工作正常,但第二次失败,因为我设置了系统属性值,而不是
HttpsURLConnection
连接。我遇到了
java.io.IOException
:写入错误:第二次打开https连接时出现I/O问题。我在应用程序中使用了以下代码

System.setProperty("http.proxyHost", proxy);
System.setProperty("http.proxyPort", port);
但是当我把它改成下面的时候,它就可以正常工作了

javax.net.ssl.HttpsURLConnection ucon = (javax.net.ssl.HttpsURLConnection) urlWPF.openConnection(proxyserver);

ucon.setRequestProperty("http.proxyHost", proxy);
ucon.setRequestProperty("http.proxyPort", port);

如果设置系统属性,它将适用于整个应用程序。如果要重置相同的值,可以采用两种方法。一个是您必须进行服务器刷新,第二个是您必须在需要时更改上面提到的
HttpsURLConnection.setRequestProperty

感谢您的回答,但恐怕这不起作用。这就是API文档所说的:URLConnection只能在实例化之后,但在连接到远程资源之前设置。在我的例子中,实际的连接发生在:conn.getInputStream()中,这是在标题设置之后。谢谢@fonetik的回答和解释!!我现在无法测试它,因为我搬到了HttpClient,但我相信这可以帮助其他人。再次感谢@user464773
System.setProperty(“http.keepAlive”、“false”)在应用程序的所有连接上禁用保持活动状态。这就是我们想要的,因为保持活力总是会导致bug。使用
conn.setRequestProperty(“连接”、“关闭”)
仅对
连接禁用Keep-Alive,当我们忘记将其添加到任何一个连接时,会为bug打开大门。我不知道这个bug是否回到了Harmony,但Android团队已经意识到了这一点:我想知道这是否仍然是可以接受的/最好的答案,或者是否有更好的建议来解决“javax.net.ssl.SSLException:Write error:ssl=0x130f4a0:I/O error in system call,break pipe”的问题?10Q当连接挂起时,禁用keepalive with setRequestProperty似乎根本不起作用。谷歌现在建议使用HttpUrlConnection(从Gingerbread开始),因为其中一些错误已经被修复:迟早,尤其是随着安卓M的发展,HttpClient会变得越来越不受欢迎。URLConnection推荐用于使用寿命较长的应用程序。