2010-10-02 6 views
0

Quelqu'un peut-il me dire où je vais me tromper avec ce code? Fondamentalement, je veux que l'application pour télécharger un fichier .png, l'afficher à l'utilisateur et également l'enregistrer sur la carte SD pour référence future. Il semble que tout se passe bien jusqu'à la partie while ((len = webstream.read(buffer)) > 0); comme le débogueur n'atteint pas le point d'arrêt que j'ai mis ici, et j'ai un répertoire de fichiers .png vides. J'ai l'autorisation WRITE_EXTERNAL_STORAGE déclarée dans mon manifeste.L'écriture de la carte SD échoue?

protected class DownloadTask extends AsyncTask<String, Integer, Bitmap> { 

    @Override 
    protected Bitmap doInBackground(String... string) { 

     Bitmap d = null; 

     try { 

      DefaultHttpClient dhc = new DefaultHttpClient(); 
      HttpGet request = new HttpGet(HTTP_BASE + string[0] + ".png"); 
      HttpResponse response = dhc.execute(request); 
      BufferedInputStream webstream = new BufferedInputStream(response.getEntity().getContent()); 
      d = BitmapFactory.decodeStream(webstream); 
      writeToSd(string[0], webstream, d); 

     } 
     catch (Exception ex) { ex.printStackTrace(); } 

     return d; 

    } 

    private void writeToSd(String string, BufferedInputStream webstream, Bitmap d) { 

     try { 

      webstream.mark(3); 
      webstream.reset(); 
      File f = new File(Environment.getExternalStorageDirectory() + SD_DIR); 
      f.mkdirs(); 
      File f2 = new File(f, string + ".png"); 
      f2.createNewFile(); 
      BufferedOutputStream fos = new BufferedOutputStream(new FileOutputStream(f2)); 

      int len; 
      byte[] buffer = new byte[1024]; 
      while ((len = webstream.read(buffer)) > 0) { 

       fos.write(buffer, 0, len); 

      } 

      webstream.close(); 
      //fos.flush(); 
      fos.close(); 

     } 
     catch (Exception ex) { 

      ex.printStackTrace(); 

     } 


    } 

    protected void onPostExecute(Bitmap result) { 

     if (result != null) { 
      iv.setImageBitmap(result); 
      vs.setDisplayedChild(1); 
     } 

    } 

}; 

Répondre

1

Je ne suis pas sûr, mais il semble probable qu'il y ait quelque chose de mal avec la re-lecture du InputStream, même si elle est tamponne. Une image est un peu de données à conserver en mémoire. Plutôt que de faire

Fetch, Image Display, Image Store

vous pouvez essayer de

Fetch, Image Store, Afficher l'image

De cette façon, vous peut écrire une image en taille réelle sur le disque (sans avoir à tamponner le flux et consommer beaucoup de mémoire). Ensuite, vous pouvez simplement charger l'image à partir de la carte SD à la fréquence d'échantillonnage la plus basse qui fonctionne pour votre application, ce qui évite d'avoir une image pleine taille en mémoire. En outre, le faire de cette manière éliminerait probablement tous les problèmes que vous pourriez ou ne pourriez pas avoir avec le bufferedInputStream - je les trouve être assez pointilleux.

+0

Yup, essayé cela et cela a fonctionné avec brio, merci! –

1

Sauf si vous voulez les octets de flux d'origine, vous pouvez écrire l'image bitmap sur le disque en utilisant Bitmap.compress(format, quality, stream). Toutefois, la réponse de Hamy est probablement la meilleure du point de vue de la conservation de la mémoire.

Questions connexes