SocketTimeoutException Android

Posted

技术标签:

【中文标题】SocketTimeoutException Android【英文标题】: 【发布时间】:2013-01-16 12:02:46 【问题描述】:

我有一个复杂的应用程序,它从我在 AWS 上的网络服务下载大量内容。但是,我一直收到SocketTimeoutException 50% 的时间。根据我的研究,我怀疑可能有以下原因:

连接超时的时间变短了:我将它增加到 100 秒,但仍然不断收到此错误。 内存泄漏:我不断收到GC 警告。我已阅读文章并尝试改进我的代码,但它也无济于事。我还必须提到,我的应用程序在后台线程中一个接一个地下载了 2000+ 30KB JSON 文件。非常欢迎提出有效即兴创作的建议! 服务器问题:由于 Amazon Web Service 高度可靠,因此可能不是根本问题。 多线程:这可能是某种原因吗? 错误的下载方式:我怀疑我是否以低效的方式下载。如果我错了,请纠正我。

请帮我找出真正的问题。谢谢!

public synchronized String getJSONString(String url)
   
    try 
           URL url1 = new URL(url);
           URLConnection tc = url1.openConnection();
           tc.setConnectTimeout(timeout);
           tc.setReadTimeout(timeout);
          // tc.connect();
           br = new BufferedReader((new InputStreamReader(tc.getInputStream())),8000);
           while ((line = br.readLine()) != null) 
                    sb.append(line+"\n");
                
                br.close();
                json = sb.toString();
                return json;
        
    catch(Exception e)
    
        Log.e("JSON Downloader", "Error downloading feed/article ");
        e.printStackTrace();
    

    return null;

错误日志:

02-01 06:37:43.375: W/System.err(5548): java.net.SocketTimeoutException
02-01 06:37:43.375: W/System.err(5548):     at java.net.PlainSocketImpl.read(PlainSocketImpl.java:491)
02-01 06:37:43.375: W/System.err(5548):     at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:46)
02-01 06:37:43.375: W/System.err(5548):     at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:240)
02-01 06:37:43.375: W/System.err(5548):     at java.io.InputStream.read(InputStream.java:163)
02-01 06:37:43.375: W/System.err(5548):     at java.io.BufferedInputStream.fillbuf(BufferedInputStream.java:142)
02-01 06:37:43.375: W/System.err(5548):     at java.io.BufferedInputStream.read(BufferedInputStream.java:227)
02-01 06:37:43.375: W/System.err(5548):     at libcore.io.Streams.readAsciiLine(Streams.java:201)
02-01 06:37:43.375: W/System.err(5548):     at libcore.net.http.HttpEngine.readResponseHeaders(HttpEngine.java:544)
02-01 06:37:43.375: W/System.err(5548):     at libcore.net.http.HttpEngine.readResponse(HttpEngine.java:784)
02-01 06:37:43.375: W/System.err(5548):     at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:274)
02-01 06:37:43.375: W/System.err(5548):     at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:168)
02-01 06:37:43.375: W/System.err(5548):     at com.in.feeds.JSONDownloader.getJSONString(JSONDownloader.java:65)
02-01 06:37:43.375: W/System.err(5548):     at com.in.feeds.JSONDownloader.getJSONObjectFromUrl(JSONDownloader.java:45)
02-01 06:37:43.375: W/System.err(5548):     at com.in.fullarticle.ArticlePage$LoadArticle.run(ArticlePage.java:383)
02-01 06:37:43.375: W/System.err(5548):     at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:442)
02-01 06:37:43.375: W/System.err(5548):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
02-01 06:37:43.375: W/System.err(5548):     at java.util.concurrent.FutureTask.run(FutureTask.java:137)
02-01 06:37:43.375: W/System.err(5548):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
02-01 06:37:43.375: W/System.err(5548):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
02-01 06:37:43.375: W/System.err(5548):     at java.lang.Thread.run(Thread.java:856)

【问题讨论】:

【参考方案1】:

我在这方面工作了一段时间,但是在寻找性能时真的建议阅读一篇文章:http://www.kegel.com/java/wp-javaio.html

连接超时可能是在服务器端引起的,假设您连接到 Web 服务器,请检查您收到的错误。

GC 语句并不令人惊讶。这不是内存泄漏,而是 Java 清理。来自上面的文章:

首先,如果我们查看 while 循环的第一行,我们会看到正在为正在读取的文件的每一行创建一个新的 String 对象:

while ((line = in.readLine()) != null)

这意味着,例如,对于 100,000 行文件,将创建 100,000 个 String 对象。创建大量对象会在三个方面产生成本:为对象分配空间的时间和内存、初始化对象的时间、垃圾收集对象的时间。

关于多线程,您应该提供更多代码。您的方法是同步的,因此您至少可以避免同时对同一个实例进行多次调用。 NW 代码一目了然,是安全的。

我的调试策略是在您收到一行输入时查看服务器端的第一和第二存储时间戳,以查看是否存在间隙(传输错误)。

祝你好运

【讨论】:

以上是关于SocketTimeoutException Android的主要内容,如果未能解决你的问题,请参考以下文章

InfluxDBIOException:java.net.SocketTimeoutException:超时

出现错误:原因:java.net.SocketTimeoutException:接受超时

尝试解决 SSLHandshakeException 时获取 SocketTimeoutException

Jsoup SocketTimeoutException:读取超时

获取 java.net.SocketTimeoutException:android 中的连接超时

SocketTimeoutException Android