2010-08-25 3 views
0

désolé pour mon anglais.La fuite de mémoire d'Android à cause de HttpClient

Je développe une application Android, consistant en différentes activités et un service qui est activé par l'activité "principale". Le service vérifie toutes les 3 secondes (cet intervalle est arbitraire) sur les connexions réseau actives dans le téléphone mobile. S'il y a une connexion à un PC à l'intérieur de mon réseau local, je fais un appel à un serveur web.

Le problème est, j'essaie d'atteindre PC hôte via cette fonction:

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

-je utiliser cette méthode, au lieu de vérifier de WifiManager et méthodes Android internes, parce que j'ai une situation comme celle-ci: je peux être connecté à un AP à cryptage ouvert, mais il a un système de connexion (coova). Ici, je peux être associé (et avoir une adresse IP dans le LAN), mais si je ne suis pas connecté, je n'aurai accès à aucun réseau, donc je dois implémenter un "network-checking-wrapper". Donc, s'il y avait une exception dans la fonction d'exécution parce que mon PC hôte n'est pas joignable, DDMS montrera comment la taille du tas et la taille de l'allocation augmenteront sans contrôle. Je pense qu'il est à cause des sous-appels à l'intérieur « exécuter » ne fermez pas correctement les références obsolètes ... par exemple, voici un exemple de suivi de l'allocation:

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 

Merci à l'avance.

+0

Hola Pacorro, Const.HOST_ADDRESS est un fichier téléchargeable ou tout simplement une page web? et avez-vous les dernières versions android sdk et eclipse? – Jorgesys

Répondre

1

Eh bien, j'ai déjà remarqué un problème. Vous avez 2 blocs try-catch séparés. Le premier attrape une exception URISyntaxException. Ensuite, dans votre deuxième tentative, appelez client.execute(). Mais s'il y a une exception dans votre premier attrapé, le client ne peut pas être instancié et votre deuxième tentative d'attraper se traduira par un NPE.

+0

Wop, c'est vrai. J'ai copié-collé le code si mal x), désolé. En supposant un réarrangement des blocs try/catch, le problème survient lorsque "client.execute" ne peut pas atteindre le PC hôte, et lance les IOExceptions, augmentant la quantité de mémoire allouée. Quelqu'un sait comment éviter ces fuites de mémoire? Merci! – pacorrop

+0

J'ai besoin de voir plus de code et avec un meilleur formatage pour en savoir plus – Falmarri

0

Vous devez fermer la connexion client en appelant client.getConnectionManager(). Shutdown() dans un bloc finally.

Votre code devient:

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