how to load internet images in gridview efficiently?

前端 未结 3 722
情深已故
情深已故 2021-01-31 06:42

I am using following example to display internet images in my activity.

http://developer.android.com/resources/tutorials/views/hello-gridview.html

In custom imag

相关标签:
3条回答
  • 2021-01-31 07:08

    Create a global and static method which returns a Bitmap. This method will take parameters: context,imageUrl, and imageName.

    in the method:

    1. check if the file already exists in the cache. if it does, return the bitmap

          if(new File(context.getCacheDir(), imageName).exists())
              return BitmapFactory.decodeFile(new File(context.getCacheDir(), imageName).getPath());
      
    2. otherwise you must load the image from the web, and save it to the cache:

      image = BitmapFactory.decodeStream(HttpClient.fetchInputStream(imageUrl));
      
      
      
      FileOutputStream fos = null;
      try {
          fos = new FileOutputStream(new File(context.getCacheDir(), imageName));
      }
      
      
      //this should never happen
      catch(FileNotFoundException e) {
          if(Constants.LOGGING)
              Log.e(TAG, e.toString(), e);
      }
      
      
      //if the file couldn't be saved
      if(!image.compress(Bitmap.CompressFormat.JPEG, 100, fos)) {
          Log.e(TAG, "The image could not be saved: " + imageName + " - " + imageUrl);
          image = BitmapFactory.decodeResource(context.getResources(), R.drawable.default_cached_image);
      }
      fos.flush();
      fos.close();
      
      
      return image;
      

    preload a Vector<SoftReference<Bitmap>> object with all of the bitmaps using the method above in an AsyncTask class, and also another List holding a Map of imageUrls and imageNames(for later access when you need to reload an image), then set your GridView adapter.

    i recommend using an array of SoftReferences to reduce the amount of memory used. if you have a huge array of bitmaps you're likely to run into memory problems.

    so in your getView method, you may have something like(where icons is a Vector holding type SoftReference<Bitmap>:

    myImageView.setImageBitmap(icons.get(position).get());
    

    you would need to do a check:

    if(icons.get(position).get() == null) {
        myImageView.setImageBitmap(defaultBitmap);
        new ReloadImageTask(context).execute(position);
    }
    

    in the ReloadImageTask AsyncTask class, simply call the global method created from above with the correct params, then notifyDataSetChanged in onPostExecute

    some additional work may need to be done to ensure you don't start this AsyncTask when it is already running for a particular item

    0 讨论(0)
  • 2021-01-31 07:09

    You could try DroidFu. My app uses the ImageCache. There's also some manner of web-based imageview or something of the sort in the library. See in particular WebImageView and WebGalleryAdapter: http://mttkay.github.com/droid-fu/index-all.html

    Edited to add: The droid-fu project is deprecated in favor of Ignition. https://github.com/mttkay/ignition

    0 讨论(0)
  • 2021-01-31 07:11

    You will need to implement the caching yourself. Create a proxy class that will download the images. In the getView ask this class to download an image by passing a url. In the proxy class create a HashMap that will map a url to a Bitmap. If the key for the passed url doesn't exist, download the image and store it. Otherwise returned the stored bitmap converted to an imageView.

    Of course you can't afford to store as many images as you like. You need to set a limit, for example 10 images, based on the image size you expect to have. When the limit is exceeded, you need to discard old images in the favor of new ones.

    0 讨论(0)
提交回复
热议问题