2017-06-18 3 views
0

Ich habe den folgenden Code für eine AsyncTask, die auf einer separaten Java-Datei (nicht innere Klasse) befinden:Android: in einem AsyncTask Speicherleck

public class LastPriceRetrieval extends AsyncTask<String,Integer,String> { 

    private String itemName; 

    public LastPriceRetrieval() { 
     Utils.incAsync(); 
    } 

    protected String doInBackground(String... strings) { 
     try { 
      itemName = strings[0]; 
      URL url = new URL("<url>?q=" + itemName); 
      HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 
      conn.connect(); 
      InputStream in = conn.getInputStream(); 
      StringBuilder stringBuilder = new StringBuilder(); 
      BufferedReader reader = new BufferedReader(new InputStreamReader(in)); 
      String line; 
      while ((line = reader.readLine()) != null) { 
       stringBuilder.append(line); 
      } 
      String body = stringBuilder.toString(); 
      reader.close(); 
      conn.disconnect(); 
      if (!body.contains("\"price\"")) return "0"; 
      else { 
       body = body.substring(body.indexOf("\"price\"")); 
       body = body.substring(body.indexOf("=\"") + 2); 
       return body.substring(0, body.indexOf("\"") - 1); 
      } 
     } catch (Exception e) { 
      return "0"; 
     } 
    } 

    protected void onPostExecute(String resLastPrice) { 
     if (Double.valueOf(resLastPrice) != 0) { 
      Utils.db.setLastPrice(itemName, Double.valueOf(resLastPrice)); 
     } 
     Utils.decAsync(); 
    } 
} 

Utils-Klasse wie folgt ist (wieder eine Datei auf seinem eigene, nicht innere Klasse)

public class Utils { 

    private static int asyncs = 0; 
    private static db = null; 

    public static synchronized void incAsync() { 
     asyncs++; 
    } 

    public static synchronized void decAsync() { 
     asyncs--; 
    } 

    public static int getAsyncs() { 
     return asyncs; 
    } 
} 

ich rufe die oben AsyncTask 60mal parallel (unterschiedliche itemName)

new LastPriceRetrieval().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, itemName); 

Utils.db ist eine SQLite-Klasse, die ich in MainActivity onCreate instanziiere. Ich mache nichts, während die 60 asynctasks laufen, zeigen Sie einfach einen ProgressDialog und warten Sie, bis es fertig ist.

Ich führe einen Speichermonitor und wenn alle 60 asynctasks fertig sind, nimmt die App mehr Speicher als zuvor, was bedeutet, dass etwas undicht ist, nicht sicher, warum oder was. Was vermisse ich?

Antwort

0

Vielleicht Anruf gc(), bevor Sie versuchen, Speicherlecks zu testen?

+0

Weil jeder Anruf (ich versuchte es dreimal hintereinander) die Speicherauslastung erhöhte, glaube ich nicht, dass das Erzwingen der GC funktioniert. Ich sehe, dass der Speicher auf und ab geht, während die 60 Anrufe verarbeitet werden. Ich dachte, es wird sich in der Nähe der Nummer beruhigen, die es vorher war, aber es steigt um 1-2 MB pro Vorgang (60 Anrufe). – Amos

+0

Wenn Sie in.close() vor reader.close() hinzufügen, macht es die Situation besser? –

+0

javadoc: reader.close() -> Schließt den Stream und gibt alle damit verbundenen Systemressourcen frei. – Amos