36 votes

Android : Chargement d'une image depuis le Web avec Asynctask

Comment remplacer les lignes de code suivantes par un Asynctask ? Comment "récupérer" le Bitmap à partir de l'Asynctask ? Merci.

ImageView mChart = (ImageView) findViewById(R.id.Chart);
String URL = "http://www...anything ...";

mChart.setImageBitmap(download_Image(URL));

public static Bitmap download_Image(String url) {

        //---------------------------------------------------
        Bitmap bm = null;
        try {
            URL aURL = new URL(url);
            URLConnection conn = aURL.openConnection();
            conn.connect();
            InputStream is = conn.getInputStream();
            BufferedInputStream bis = new BufferedInputStream(is);
            bm = BitmapFactory.decodeStream(bis);
            bis.close();
            is.close();
        } catch (IOException e) {
            Log.e("Hub","Error getting the image from server : " + e.getMessage().toString());
        } 
        return bm;
        //---------------------------------------------------

    }

J'ai pensé à quelque chose comme ça :

remplacer :

mChart.setImageBitmap(download_Image(graph_URL));

par quelque chose comme :

mChart.setImageBitmap(new DownloadImagesTask().execute(graph_URL));

y

public class DownloadImagesTask extends AsyncTask<String, Void, Bitmap> {

@Override
protected Bitmap doInBackground(String... urls) {
    return download_Image(urls[0]);
}

@Override
protected void onPostExecute(Bitmap result) {
    mChart.setImageBitmap(result);              // how do I pass a reference to mChart here ?
}

private Bitmap download_Image(String url) {
    //---------------------------------------------------
    Bitmap bm = null;
    try {
        URL aURL = new URL(url);
        URLConnection conn = aURL.openConnection();
        conn.connect();
        InputStream is = conn.getInputStream();
        BufferedInputStream bis = new BufferedInputStream(is);
        bm = BitmapFactory.decodeStream(bis);
        bis.close();
        is.close();
    } catch (IOException e) {
        Log.e("Hub","Error getting the image from server : " + e.getMessage().toString());
    } 
    return bm;
    //---------------------------------------------------
}

}

Mais comment puis-je passer une référence à mChart dans onPostExecute(Bitmap result) ? Dois-je la passer avec l'URL d'une manière ou d'une autre ? Je voudrais remplacer toutes mes lignes de code :

mChart1.setImageBitmap(download_Image(URL_1));
mChart2.setImageBitmap(download_Image(URL_2));

avec quelque chose de similaire ... mais en mode Asynctask !

mChart1.setImageBitmap(new DownloadImagesTask().execute(graph_URL_1));
mChart2.setImageBitmap(new DownloadImagesTask().execute(graph_URL_2));

Existe-t-il une solution simple pour cela ? Est-ce que je me trompe ?

75voto

Janusz Points 52607

S'il n'y a pas de raison valable de télécharger l'image vous-même, je vous recommande d'utiliser la méthode suivante Picasso .

Picasso vous épargne tous les problèmes de téléchargement, de paramétrage et de mise en cache des images. L'ensemble du code nécessaire pour un exemple simple est :

Picasso.with(context).load(url).into(imageView);

Si vous voulez vraiment tout faire vous-même, utilisez mon ancienne réponse ci-dessous.


Si l'image n'est pas si grande, vous pouvez simplement utiliser une classe anonyme pour la tâche asynchrone. Ce serait comme ceci :

ImageView mChart = (ImageView) findViewById(R.id.imageview);
String URL = "http://www...anything ...";

mChart.setTag(URL);
new DownloadImageTask.execute(mChart);

La classe Task :

public class DownloadImagesTask extends AsyncTask<ImageView, Void, Bitmap> {

ImageView imageView = null;

@Override
protected Bitmap doInBackground(ImageView... imageViews) {
    this.imageView = imageViews[0];
    return download_Image((String)imageView.getTag());
}

@Override
protected void onPostExecute(Bitmap result) {
    imageView.setImageBitmap(result);
}

private Bitmap download_Image(String url) {
   ...
}

Cacher l'URL dans la balise est un peu délicat mais c'est plus joli dans la classe d'appel si vous avez beaucoup d'images que vous voulez remplir de cette façon. C'est également utile si vous utilisez l'ImageView dans une ListView et que vous voulez savoir si l'ImageView a été recyclée pendant le téléchargement de l'image.

J'ai écrit "si votre image n'est pas si grande" parce que la tâche aura un pointeur implicite sur l'activité sous-jacente, ce qui obligera le ramasseur d'ordures à conserver l'activité entière en mémoire jusqu'à ce que la tâche soit terminée. Si l'utilisateur passe à un autre écran de votre application pendant que le bitmap est en train de se télécharger, la mémoire ne peut pas être libérée et cela peut rendre votre application et l'ensemble du système plus lents.

23voto

AboZeid Points 98

Essayez ce code :

ImageView myFirstImage = (ImageView) findViewById(R.id.myFirstImage);
ImageView mySecondImage = (ImageView) findViewById(R.id.mySecondImage);
ImageView myThirdImage = (ImageView) findViewById(R.id.myThirdImage);

String URL1 = "http://www.google.com/logos/2013/estonia_independence_day_2013-1057005.3-hp.jpg";
String URL2 = "http://www.google.com/logos/2013/park_su-geuns_birthday-1055005-hp.jpg";
String URL3 = "http://www.google.com/logos/2013/anne_cath_vestlys_93rd_birthday-1035005-hp.jpg";

myFirstImage.setTag(URL1);
mySecondImage.setTag(URL2);
myThirdImage.setTag(URL3);

new DownloadImageTask.execute(myFirstImage);
new DownloadImageTask.execute(mySecondImage);
new DownloadImageTask.execute(myThirdImage);

public class DownloadImagesTask extends AsyncTask<ImageView, Void, Bitmap> {

    ImageView imageView = null;

    @Override
    protected Bitmap doInBackground(ImageView... imageViews) {
        this.imageView = imageViews[0];
        return download_Image((String)imageView.getTag());
    }

    @Override
    protected void onPostExecute(Bitmap result) {
        imageView.setImageBitmap(result);
    }

    private Bitmap download_Image(String url) {

        Bitmap bmp =null;
        try{
            URL ulrn = new URL(url);
            HttpURLConnection con = (HttpURLConnection)ulrn.openConnection();
            InputStream is = con.getInputStream();
            bmp = BitmapFactory.decodeStream(is);
            if (null != bmp)
                return bmp;

            }catch(Exception e){}
        return bmp;
    }
}

2voto

Umesh Points 2717

Vous pouvez créer une classe, disons BkgProcess, qui contient une classe interne qui étend AsyncTask. lors de l'instanciation de BkgProcess, passez le contexte de votre classe Activity dans le constructeur de BkgProcess. par ex :

public class BkgProcess {

 String path;   
 Context _context;

public Download(Downloader downloader, String path2){

 this.path = path2;
    _context = downloader;

}

public void callProgressDialog(){

new BkgProcess().execute((Void)null);
}
class Downloads extends AsyncTask<Void, Void, Boolean> {
    private ProgressDialog dialog = new ProgressDialog(_context);
    protected void onPreExecute(){
        dialog.setMessage("Downloading image..");
        dialog.show();
    }

    protected void onPostExecute(Boolean success) {
        dialog.dismiss();
        if(success)
            Toast.makeText(_context, "Download complete", Toast.LENGTH_SHORT).show();
    }

@Override
protected Boolean doInBackground(Void... params) {
    return(startDownload(path));

    }

public boolean startDownload(String img_url) {

// download img..

      return true;
}
}
}

de votre classe d'activité..

BkgProcess dwn = new BkgProcess (Your_Activity_class.this, img_path);

dwn.callProgressDialog();

1voto

Umesh Points 2717

Cela vous permettra d'obtenir des images de n'importe quelle taille... si vous ne voulez pas le dialogue de progression, commentez simplement les codes dans onPreExecute() ;

for(int i = 0 ; i < no_of_files ; i++ )
 new FetchFilesTask().execute(image_url[i]);

private class FetchFilesTask extends AsyncTask<String, Void, Bitmap> {

    private ProgressDialog dialog = new ProgressDialog(FileExplorer.this);
    Bitmap bitmap[];
    protected void onPreExecute(){
        dialog.setMessage("fetching image from the server");
        dialog.show();
    }

     protected Bitmap doInBackground(String... args) {

             bitmap = getBitmapImageFromServer();
         return bitmap;
     }

     protected void onPostExecute(Bitmap m_bitmap) {
         dialog.dismiss();
         if(m_bitmap != null)
             //store the images in an array or do something else with all the images.   
     }
 }

public Bitmap getBitmapImageFromServer(){

    // fetch image form the url using the URL and URLConnection class
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X