在安卓4.2上,httpurlconnection非常慢

12
我可以使用HttpURLConnection成功连接、发送和接收数据。但是在我的手机(Samsung s4,4.2)和Android 4.2模拟器上加载所有数据需要很长时间。但在Android 2.3.x模拟器上加载图片几乎只需要1-2秒钟(非常快),比在http连接下的我的galaxy s4要快。
我正在使用AsyncTask,我的代码在两者上都可以正常工作,只是在Android 4.2上速度较慢。我尝试了删除chunkedStreaming、保持连接、更改超时值等,但仍然没有成功。
以下是我的代码:
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
                 urlConnection.setRequestMethod("POST");
                 urlConnection.setDoOutput(true);
                 urlConnection.setDoInput(true); 

                 urlConnection.setUseCaches(false);
                 urlConnection.setChunkedStreamingMode(0);
                 urlConnection.setRequestProperty("Connection", "Keep-Alive");
                 urlConnection.setConnectTimeout(6000);
                 urlConnection.setReadTimeout(6000);
                 urlConnection.setRequestProperty("Content-Type", "multipart/form-data;charset=UTF-8;boundary="+boundary);

                 urlConnection.connect();

4.2版本和2.3.x版本的httpurlconnections有什么区别?这里是什么问题?

更新!

我使用Log.e()进行测试,以查看哪一行需要最长时间。

///// other staff
////......
                     Log.e("HTTP","3");

                 if (isCancelled())
                        return (null); // don't forget to terminate this method
                 Log.e("HTTP","3");
                 //Output
                    DataOutputStream outputStream = new DataOutputStream( urlConnection.getOutputStream() );
                    //Send Passcode
                    Log.e("HTTP","4");

电话线路传输3至4个数字,需要5-6秒钟。

DataOutputStream outputStream = new DataOutputStream( urlConnection.getOutputStream() );

更新!!

之前提到的等待时间与urlConnection.setConnectTimeout(6000)有关。

当我将超时时间设为1000时,连接会快速响应(等待1秒钟即可收到回应)。

DataOutputStream outputStream = new DataOutputStream( urlConnection.getOutputStream() );

不知道为什么会发生这种情况。

你不需要设置setDoInput,同时将DoOutput设置为true会自动将方法设置为POST,所以你不需要设置setRequestMethod。我从来没有需要设置任何超时、requestProperty或chunkedStreamingMode,你试过删除它们吗?我也不使用.connect(),我在设置请求参数后立即getOutputStream()getInputStream() - Gal Ben-Haim
1
你在结尾处使用 .disconnect() 了吗?一种常见的方法是将 urlConnection 代码包装在 try/catch/finally 块中,并在 finally 中调用 urlConnection.disconnect()。 - Gal Ben-Haim
2个回答

4
将urlConnection.setConnectTimeout()设置为较低的超时时间。
URLConnection.setConnectTimeout()的类文档说:
设置连接时等待的最长时间(以毫秒为单位)。如果在建立连接之前超时时间到期,将使用SocketTimeoutException连接服务器失败。默认值为0会使我们进行阻塞连接。这并不意味着我们永远不会超时,但这可能意味着您将在几分钟后获得TCP超时。
警告:如果主机名解析为多个IP地址,则此客户端将按照RFC 3484顺序尝试每个IP地址。如果连接到这些地址中的每个地址都失败,则在连接尝试抛出异常之前将经过多个超时时间。同时支持IPv6和IPv4的主机名始终至少有2个IP地址。
我最初将其设置为urlConnection.setConnectTimeout(30000) ,然后将其更改为urlConnection.setConnectTimeout(1000) 。立即看到更快的结果。
希望对你有所帮助!

1
注意:我意识到这只是一种被感知的影响,而我实际上并没有尝试找到根本原因。但是,我认为这可能仍然有助于人们。 - w3bshark

1
你提到你正在使用AsyncTask,你是想同时运行多个任务吗?
如果是这样的话,你应该知道从Android 4.0开始,默认情况下AsyncTasks是串行的。这意味着执行器每次只会运行一个任务。
如果你想保持以前的行为,可以使用以下结构:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
  myTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
else {
  myTask.execute();
}

请参阅此博客文章以获取更多信息:
http://commonsware.com/blog/2012/04/20/asynctask-threading-regression-confirmed.html


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接