Утечка памяти в Android из-за HttpClient - PullRequest
0 голосов
/ 25 августа 2010

извините за мой английский.

Я разрабатываю приложение для Android, состоящее из различных действий и службы, которая активируется "основной" деятельностью. Сервис каждые 3 секунды проверяет (этот интервал произвольный) на предмет активных сетевых подключений к мобильному телефону. Если в моей локальной сети есть соединение с ПК, я звоню на веб-сервер.

Проблема в том, что я пытаюсь связаться с ПК через эту функцию:

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, потому что у меня такая ситуация: я могу быть подключен к точке доступа с открытым шифрованием, но у него есть система входа в систему (coova). Здесь я могу быть связан (и у меня есть IP-адрес внутри локальной сети), но если я не вошел в систему, у меня не будет доступа к какой-либо сети, поэтому я должен реализовать «проверку сети».

Итак, если в функции execute возникла исключительная ситуация, поскольку мой хост-компьютер недоступен, DDMS покажет мне, как размер кучи и размер выделения будут расти без контроля. Я подозреваю, что это из-за того, что вложенные вызовы внутри "execute" не закрывают должным образом устаревшие ссылки ... например, вот пример трекера выделения:

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 ]

1 голос
/ 25 августа 2010

Ну, я уже заметил одну проблему. У вас есть 2 отдельных блока try-catch. Первый перехватывает URISyntaxException. Затем во второй попытке try вы вызываете client.execute (). Но если в вашем первом улове есть исключение, клиент не может быть создан, а ваш второй улов приведет к NPE.

0 голосов
/ 22 сентября 2012

Вы должны закрыть клиентское соединение, вызвав client.getConnectionManager (). Shutdown () в finally-Block.

Ваш код становится:

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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...