2011-04-04 5 views
1

Je suis novice avec Android et deux derniers jours, je ne peux pas trouver la cause d'un problème:Comment télécharger et afficher bitmaps avec AsyncTask

J'ai ActivityA avec un ListView. Chaque élément de ce ListView au clic ouvrira ActivityB, qui affichera un certain nombre d'images téléchargées à partir du Web dans un ImageView. Ainsi, dans ActivityB, j'ai une boucle avec le code suivant pour essayer de télécharger les images:

ImageView ivPictureSmall = new ImageView(this); 
ImageDownloader ido = new ImageDownloader(); 
ido.download(this.getResources().getString(R.string.images_uri) + strPictureSmall, ivPictureSmall); 
ivPictureSmall.setPadding(3, 5, 3, 5); 
linearLayout.addView(ivPictureSmall); 

Classe ImageDownloader


public class ImageDownloader 
{ 
    public void download(String url, ImageView imageView) 
    { 
      BitmapDownloaderTask task = new BitmapDownloaderTask(imageView); 
      task.execute(url); 
    } 
} 

Classe BitmapDownloaderTask


class BitmapDownloaderTask extends AsyncTask 
{ 
    private String url; 
    private final WeakReference imageViewReference; 

    public BitmapDownloaderTask(ImageView imageView) 
    { 
     imageViewReference = new WeakReference(imageView); 
    } 

    @Override 
    // Actual download method, run in the task thread 
    protected Bitmap doInBackground(String... params) 
    { 
     // params comes from the execute() call: params[0] is the url. 
     return downloadBitmap(params[0]); 
    } 

    @Override 
    // Once the image is downloaded, associates it to the imageView 
    protected void onPostExecute(Bitmap bitmap) 
    { 
     if (isCancelled()) 
     { 
      bitmap = null; 
     } 

     if (imageViewReference != null) 
     { 
      ImageView imageView = imageViewReference.get(); 
      if (imageView != null) { 
       imageView.setImageBitmap(bitmap); 
      } 
     } 

    } 

    protected Bitmap downloadBitmap(String url) 
    { 
     final DefaultHttpClient client = new DefaultHttpClient(); 
     final HttpGet getRequest = new HttpGet(url); 

     try { 
      HttpResponse response = client.execute(getRequest); 
      final int statusCode = response.getStatusLine().getStatusCode(); 
      if (statusCode != HttpStatus.SC_OK) { 
       Log.w("ImageDownloader", "Error " + statusCode + " while retrieving bitmap from " + url); 
       return null; 
      } 
      final HttpEntity entity = response.getEntity(); 
      if (entity != null) { 
       InputStream inputStream = null; 
       try { 
        inputStream = entity.getContent(); 
        final Bitmap bitmap = BitmapFactory.decodeStream(new FlushedInputStream(inputStream)); 
        return bitmap; 
       } finally { 
        if (inputStream != null) { 
         inputStream.close(); 
        } 
        entity.consumeContent(); 
       } 
      } 
     } catch (Exception e) { 
      // Could provide a more explicit error message for IOException or IllegalStateException 
      getRequest.abort(); 
      Log.w("ImageDownloader", "Error while retrieving bitmap from: " + e.toString()); 
     } finally { 
      if (client != null) { 
       //client.close(); 

      } 
     } 
     return null; 
    } 


    static class FlushedInputStream extends FilterInputStream 
    { 
     public FlushedInputStream(InputStream inputStream) 
     { 
      super(inputStream); 
     } 

     @Override 
     public long skip(long n) throws IOException 
     { 
      long totalBytesSkipped = 0L; 
      while (totalBytesSkipped

Lorsque j'ai cliqué sur un élément dans ListView dans ActivityA, il va correctement à ActivityB, et ActivityB montre les images. Lorsque j'appuie sur le bouton "Retour" sur ActivityB pour sauvegarder jusqu'à ActivityA, puis cliquez à nouveau sur un élément dans le ListView, je viens à ActivityB et puis je vois suis informé que le processus s'est fermé de façon inattendue.

Lorsque je tente de déboguer, je remarquais que le problème est dans la ligne:

final Bitmap bitmap = BitmapFactory.decodeStream(new FlushedInputStream(inputStream)); 

Ce qui est en fonction protected Bitmap downloadBitmap(String url). J'ai lu sur un bug dans Android avec BitmapFactory.decodeStream donc j'ai ajouté FlushedInputStream pour l'empêcher.

Cependant, il me semble que ce n'est pas la cause du problème, car il fonctionnait quand j'ai d'abord chargé ActivityB, mais pas la deuxième fois. Peut-être que j'ai une fuite de mémoire? (Les images sont grandes, et la mémoire ne sont pas recyclées après le retour à ActivityA.)

Si oui, comment puis-je nettoyer la mémoire associée? Ou est le problème dans quelque chose d'autre?

Pour référence: Mes images sont au format .jpg, j'ai essayé de les convertir en .png, mais j'ai eu les mêmes problèmes.

+0

Votre question est beaucoup trop longue. Vous demandez aux gens de déboguer votre code pour vous, et la plupart n'ont pas le temps ... –

+1

bien, j'ai essayé de donner toutes les informations relevent .. je pensais qu'il y a quelques problème obviuos dans le code que je ne vois pas parce que je Suis novice dans android et java. – Timun

+0

vous devriez ajouter system.gc() pour libérer de la mémoire –

Répondre

0

Vous devez utiliser une bibliothèque de chargement d'image telle que Picasso ou pour effectuer le travail dur pour vous.

Questions connexes