How to set image from Url using AsyncTask?

后端 未结 7 1341
青春惊慌失措
青春惊慌失措 2021-02-06 14:18

I\'m a newbie programmer an I\'m making an android program that displays an image on ImageView from a given url. My problem is how do you use this on the AsyncTask?

Thes

7条回答
  •  耶瑟儿~
    2021-02-06 14:29

    well, I dont know why android SDK does not provide support for it (yet) I extended the ImageView class by UrlImageView class with asynchronous loading and caching support. I put the code of my class below, which is plug and play. The class body is at the end of my post, now I write two lines how to use it the convenient way.

    Two more methods now are supported:

    setImageUrl(URL url) // sets the bitmap by its URL
    cancelLoading();     // tell this view to cancel pending load
    

    How to use your java-code:

    // [somewhere in your activity]
    UrlImageView urlImg = new UrlImageView(this).setImageUrl("http://abc.png");
    ...
    urlImg.setImageUrl("http://abc2.png"); // works like expected
    

    How to bind in your layouts:

    
    
    

    ..and again in your activity java code:

    ((UrlImageView)findViewById(R.id.thumbnail)).setImageUrl("http://foo.bar.png");
    

    I use it in lists with more than 100 entries - flinging very well. Here the class body, you can use it, modify it, extend it, whatever you like:

    package com.gplushub.android.view;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.URL;
    import java.net.URLConnection;
    
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.drawable.Drawable;
    import android.net.Uri;
    import android.os.AsyncTask;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.widget.ImageView;
    
    /**
     * an {@link ImageView} supporting asynchronous loading from URL. Additional
     * APIs: {@link #setImageURL(URL)}, {@link #cancelLoading()}.
     * 
     * @author ep@gplushub.com / Eugen Plischke
     * 
     */
    public class UrlImageView extends ImageView {
      private static class UrlLoadingTask extends AsyncTask {
        private final ImageView updateView;
        private boolean         isCancelled = false;
        private InputStream     urlInputStream;
    
        private UrlLoadingTask(ImageView updateView) {
          this.updateView = updateView;
        }
    
        @Override
        protected Bitmap doInBackground(URL... params) {
          try {
            URLConnection con = params[0].openConnection();
            // can use some more params, i.e. caching directory etc
            con.setUseCaches(true);
            this.urlInputStream = con.getInputStream();
            return BitmapFactory.decodeStream(urlInputStream);
          } catch (IOException e) {
            Log.w(UrlImageView.class.getName(), "failed to load image from " + params[0], e);
            return null;
          } finally {
            if (this.urlInputStream != null) {
              try {
                this.urlInputStream.close();
              } catch (IOException e) {
                ; // swallow
              } finally {
                this.urlInputStream = null;
              }
            }
          }
        }
    
        @Override
        protected void onPostExecute(Bitmap result) {
          if (!this.isCancelled) {
            // hope that call is thread-safe
            this.updateView.setImageBitmap(result);
          }
        }
    
        /*
         * just remember that we were cancelled, no synchronization necessary
         */
        @Override
        protected void onCancelled() {
          this.isCancelled = true;
          try {
            if (this.urlInputStream != null) {
              try {
                this.urlInputStream.close();
              } catch (IOException e) {
                ;// swallow
              } finally {
                this.urlInputStream = null;
              }
            }
          } finally {
            super.onCancelled();
          }
        }
      }
    
      /*
       * track loading task to cancel it
       */
      private AsyncTask currentLoadingTask;
      /*
       * just for sync
       */
      private Object                       loadingMonitor = new Object();
    
      public UrlImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
      }
    
      public UrlImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
      }
    
      public UrlImageView(Context context) {
        super(context);
      }
    
      @Override
      public void setImageBitmap(Bitmap bm) {
        cancelLoading();
        super.setImageBitmap(bm);
      }
    
      @Override
      public void setImageDrawable(Drawable drawable) {
        cancelLoading();
        super.setImageDrawable(drawable);
      }
    
      @Override
      public void setImageResource(int resId) {
        cancelLoading();
        super.setImageResource(resId);
      }
    
      @Override
      public void setImageURI(Uri uri) {
        cancelLoading();
        super.setImageURI(uri);
      }
    
      /**
       * loads image from given url
       * 
       * @param url
       */
      public void setImageURL(URL url) {
        synchronized (loadingMonitor) {
          cancelLoading();
          this.currentLoadingTask = new UrlLoadingTask(this).execute(url);
        }
      }
    
      /**
       * cancels pending image loading
       */
      public void cancelLoading() {
        synchronized (loadingMonitor) {
          if (this.currentLoadingTask != null) {
            this.currentLoadingTask.cancel(true);
            this.currentLoadingTask = null;
          }
        }
      }
    }
    

提交回复
热议问题