开发者

Android's memory leak because of HttpClient

sorry for my English.

I'm developing an Android application, consisting in various activities and a service which is activated by "main" activity. The service checks every 3 seconds (this interval is arbitrary) about active network connections into mobile phone. If there's a connection to a PC inside my local network, I then make a call to a web server there.

The problem is, I try to reach host PC through this function:

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.setCon开发者_如何学GonectionTimeout(httpParams, 1000);

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

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

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

I do use this method, instead of checking WifiManager's and internal Android methods, because I have a situation like this: I can be connected to an open-encryption AP, but it has a login system (coova). Here, I can be associated (and have an IP inside LAN), but if I'm not logged I won't have access to any network, so I have to implement a "network-checking-wrapper".

So, if there was an exception in execute function because my host PC isn't reachable, DDMS will show me how heap size and allocation size will grow without control. I suspect that it's because of the sub-calls inside "execute" don't properly close obsolete references... for instance, here's a example of allocation tracker:

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 

Thanks in advance.


Well I've already noticed one problem. You have 2 separate try-catch blocks. The first one catches a URISyntaxException. You then, in your second try-catch, call client.execute(). But if there's an exception in your first catch, client may not be instantiated and your second try-catch will result in an NPE.


You should close the client connection by calling client.getConnectionManager().shutdown() in a finally-Block.

Your code becomes:

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;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜