由于HttpClient,Android的内存泄漏

时间:2010-08-25 19:07:49

标签: android memory-leaks httpclient

抱歉我的英语。

我正在开发一个Android应用程序,包含各种活动和由“主要”活动激活的服务。该服务每隔3秒(此间隔是任意的)检查有关进入移动电话的活动网络连接。如果我的本地网络中有PC连接,那么我就打电话给那里的Web服务器。

问题是,我尝试通过此功能到达主机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),但如果我没有登录,我将无法访问任何网络,因此我必须实现“网络检查包装器”。

因此,如果执行函数中存在异常,因为我的主机PC无法访问,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 

提前致谢。

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

您应该通过在finally-Block中调用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;
}