How to set image from Url using AsyncTask?

后端 未结 7 1226
青春惊慌失措
青春惊慌失措 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:

    <!-- thumbnail -->
    <com.gplushub.android.view.UrlImageView
        android:id="@+id/thumbnail"
        android:layout_width="64dp"
        android:layout_height="64dp"
        android:layout_gravity="center_vertical"
        android:layout_marginRight="2dp"
        android:scaleType="fitXY" />
    

    ..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<URL, Void, Bitmap> {
        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<URL, Void, Bitmap> 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;
          }
        }
      }
    }
    
    0 讨论(0)
  • 2021-02-06 14:30

    You are right when u do any network operation later Android 2.2(Froyo) Must use Asynctask

    This is the best example to understand AsyncTask

    0 讨论(0)
  • 2021-02-06 14:36

    If the image is not that big you can just use an anonymous class for the async task. This would like this:

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

    and the task class is

    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) {
           ...
       }
    
    0 讨论(0)
  • 2021-02-06 14:40

    Try this code, make your drawable variable global and change your satellite function like this:

    private void satellite() {
          // TODO Auto-generated method stub
          ImageView imgView =(ImageView)findViewById(R.id.satellite);
          new yourTask().execute();
    }
    

    then create asyncTask class like this:

    private class yourTask extends AsyncTask<Integer, Void, Integer> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            //show a progress bar
        }
    
        @Override
        protected String doInBackground(Integer... params) {
            drawable  =  LoadImageFromWeb("http://www.pagasa.dost.gov.ph/wb/sat_images/satellite.gif"); 
            return 0; 
        }      
    
        @Override
        protected void onPostExecute(Integer result) {
            super.onPostExecute(result);
            imgView.setImageDrawable(drawable);   
        }
    }
    
    0 讨论(0)
  • 2021-02-06 14:42

    Here is the code for the Aynctask implementation Make your drawable object as global in Aynctask class.

    Class MyDownloader extends AsyncTask<Void,Void,String>{
    
        Drawable drawable;    
        @Override
        public String doInBackground(Void... args){
    
            drawable = LoadImageFromWeb("http://www.pagasa.dost.gov.ph/wb/sat_images/satellite.gif");
            return null; // here you can pass any string on response as on error or on success
    
        }
    
        public void onPostExecute(String result){
    
            if(drawable!=null){
    
                imgView.setImageDrawable(drawable);
    
            }
    
        }
    
    }
    

    now create object of this class and execute it

    private void satellite() {
        // TODO Auto-generated method stub
      ImageView imgView =(ImageView)findViewById(R.id.satellite);
      new MyDownloader.execute();
    
    }
    

    Here is good example link for caching the image check out this link and example

    https://github.com/novoda/ImageLoader

    0 讨论(0)
  • 2021-02-06 14:44

    Just create a new class "DownloadImageTask" like following one and put it at the same folder where you have your Activity.

    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.util.Log;
    import android.widget.ImageView;
    import android.os.AsyncTask;
    import java.io.*;
    
    
    public class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
        ImageView bmImage;
    
        public DownloadImageTask(ImageView bmImage) {
            this.bmImage = bmImage;
        }
    
        protected Bitmap doInBackground(String... urls) {
            String urldisplay = urls[0];
            Bitmap myImage = null;
            try {
                InputStream in = new java.net.URL(urldisplay).openStream();
                myImage = BitmapFactory.decodeStream(in);
            } catch (Exception e) {
                Log.e("Error", e.getMessage());
                e.printStackTrace();
            }
            return myImage;
        }
    
        protected void onPostExecute(Bitmap result) {
            bmImage.setImageBitmap(result);
        }
    }
    

    After this add line to crate that class in your Activity.

    import android.graphics.Bitmap;
    import android.os.AsyncTask;
    import android.support.v7.app.ActionBarActivity;
    import android.os.Bundle;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.util.Log;
    import android.widget.ImageView;
    
    
    public class HomeScreen extends ActionBarActivity {
    
        private final String TAG = "test1";
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            Log.d(TAG, "onCreate");
            setContentView(R.layout.activity_home_screen);
            InitHomeScreen();
        }
    
        protected void InitHomeScreen()
        {
            String imageUrl = "http://s20.postimg.org/4t9w2pdct/logo_android_png.png";
            Log.d(TAG, "Get an Image");
            // Get an Image
            try{
                AsyncTask<String, Void, Bitmap> execute = new DownloadImageTask((ImageView) findViewById(R.id.imageView))
                        .execute(imageUrl);
                  // R.id.imageView  -> Here imageView is id of your ImageView
            }
            catch(Exception ex)
            {
            }
        }
    
       // Other code...
    

    Don't forget to allow access to INTERNET to your Android app.

    Check your manifest file.

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.dmitry.myapplication1" >
    
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
        <uses-permission android:name="android.permission.INTERNET" />
    
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/AppTheme" >
            <activity
                android:name=".HomeScreen"
                android:label="@string/app_name" >
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        </application>
    
    </manifest>
    
    0 讨论(0)
提交回复
热议问题