2010-08-25 85 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; 
}