2010-08-25 60 views
0

对不起我的英文。Android的内存泄漏,因为HttpClient

我正在开发一个Android应用程序,包含各种活动和由“主要”活动激活的服务。该服务每隔3秒钟检查一次(此间隔是任意的),以检查手机中的活动网络连接。如果我的本地网络内部连接了一台PC,那么我会打电话给那里的网络服务器。

的问题是,我试图通过这个功能来达到PC主机:

public boolean checkNet() { 
    HttpClient client; 
    HttpPost postMethod; 
    HttpParams httpParams; 
    URI uri; 

    try { 
     uri = new URI(Const.HOST_ADDRESS); 
     postMethod = new HttpPost(uri); 
     postMethod.addHeader("Content-Type", "text/xml"); 

     httpParams = postMethod.getParams(); 
     HttpConnectionParams.setSoTimeout(httpParams, 1000); 
     HttpConnectionParams.setSocketBufferSize(httpParams, 512); 
     HttpConnectionParams.setStaleCheckingEnabled(httpParams, false); 
     HttpConnectionParams.setConnectionTimeout(httpParams, 1000); 

     client = new DefaultHttpClient(); 
    } 
    catch (URISyntaxException use) {} 

    try 
    { 
     client.execute(postMethod); 
     return true; 
    } 
    catch (ClientProtocolException cpe) { 

    } 
    catch (IOException e) { 
    } 
    return false; 
} 

我使用这种方法,而不是检查WifiManager的和内部的Android方法,因为我有这样的情况:我可以被连接到一个开放加密的AP,但它有一个登录系统(coova)。在这里,我可以关联(并且在局域网内有一个IP),但是如果我没有登录,我将无法访问任何网络,所以我必须实现一个“网络检查包装器”。

因此,如果执行功能出现异常,因为我的主机无法访问,DDMS将向我展示堆大小和分配大小如何在没有控制的情况下增长。我怀疑这是因为里面的“执行”的分话费不正常关闭过时的参考...例如,这里的分配跟踪器的例子:

java.lang.AbstractStringBuilder enlargeBuffer AbstractStringBuilder.java 99 false 
java.lang.AbstractStringBuilder append0 AbstractStringBuilder.java 170 false 
java.lang.StringBuilder append StringBuilder.java 224 false 
org.apache.http.conn.HttpHostConnectException <init> HttpHostConnectException.java 48 false 
org.apache.http.impl.conn.DefaultClientConnectionOperator openConnection DefaultClientConnectionOperator.java 133 false 
org.apache.http.impl.conn.AbstractPoolEntry open AbstractPoolEntry.java 164 false 
org.apache.http.impl.conn.AbstractPooledConnAdapter open AbstractPooledConnAdapter.java 119 false 
org.apache.http.impl.client.DefaultRequestDirector execute DefaultRequestDirector.java 348 false 

在此先感谢。

+0

HOLA pacorro,Const.HOST_ADDRESS是一个可下载的文件或只是一个网页?你有最后一个android sdk和eclipse版本吗? – Jorgesys 2010-08-25 20:40:19

回答

1

嗯,我已经注意到一个问题。你有2个独立的try-catch块。第一个捕获URISyntaxException。然后,在第二次try-catch中,调用client.execute()。但是如果你的第一次捕获有一个异常,客户端可能不会被实例化,而你的第二次尝试捕获将导致一个NPE。

+0

Wop,这是真的。我已经复制粘贴代码太糟糕了),抱歉。假设对try/catch块进行重新排序,当“client.execute”无法到达主机PC时会发生问题,并抛出IOExceptions,从而增加分配的内存量。任何人都知道如何避免这些内存泄漏?谢谢! – pacorrop 2010-08-25 19:45:36

+0

我需要看到更多的代码和更好的格式来告诉更多 – Falmarri 2010-08-25 19:55:12

0

您应该通过在finally块中调用client.getConnectionManager()。shutdown()来关闭客户端连接。

您的代码就变成了:

public boolean checkNet() { 
    HttpClient client = null; 
    HttpPost postMethod; 
    HttpParams httpParams; 
    URI uri; 
    boolean result = false; 

    try { 
     uri = new URI(Const.HOST_ADDRESS); 
     postMethod = new HttpPost(uri); 
     postMethod.addHeader("Content-Type", "text/xml"); 

     httpParams = postMethod.getParams(); 
     HttpConnectionParams.setSoTimeout(httpParams, 1000); 
     HttpConnectionParams.setSocketBufferSize(httpParams, 512); 
     HttpConnectionParams.setStaleCheckingEnabled(httpParams, false); 
     HttpConnectionParams.setConnectionTimeout(httpParams, 1000); 

     client = new DefaultHttpClient(); 
     client.execute(postMethod); 
     result = true; 
    } catch (URISyntaxException use) { 
    } catch (ClientProtocolException cpe) { 
    } catch (IOException e) { 
    } finally { 
     if (client != null && client.getConnectionManager() != null) { 
      client.getConnectionManager().shutdown(); 
      client = null; 
     } 
    } 
    return result; 
}