Volley Image Caching

后端 未结 7 2041
臣服心动
臣服心动 2020-12-09 18:18

I am trying to understand Volley\'s image caching. I have a fragment with gridview inside it, which will load around 12-30 images. There images are retrieved from server and

相关标签:
7条回答
  • 2020-12-09 18:53

    Volley did not gave caching option directly. you have to make your own with in the tool provide by Volley. See Network Image caching, Jake Wharton had written about caching mechanism using Volley. Jake Wharton's Volley Customization

    0 讨论(0)
  • 2020-12-09 18:53

    Are you using Volley as a singleton? If you're not, and you're not using a common context for the requestQueue, it won't work the way you expect. The documentation on this part of Volley is particularly unhelpful (at least since I used it last). Once configured properly it will read/write from the cache as you would expect.

    Here is a GitHub project with a VolleySingleton class you can use along with examples: CypressNorth/Volley-Singleton

    Here is a blog post describing the setup in more detail: Setting up the Android Google Volley ImageLoader for NetworkImageView

    0 讨论(0)
  • 2020-12-09 18:55

    You can see in the link below, the continuation of my question for implementing Image Caching with Volley using Jake Wharton's DiskLruCache and VolleyImageCacheExample. It's working as expected and images are getting cached. Thanks for all your help.

    JakeWharton's DiskLruCache - How to Implement with Volley?

    0 讨论(0)
  • 2020-12-09 19:00

    The simplest way to cache images with Volley I found, was to use a RequestQueue with a DiskBasedCache. My goal was to reduce bandwidth, rather than loading times. This keeps the memory footprint low as well.

     val cacheSizeInMegabytes = 5
     val cacheSizeInBytes = cacheSizeInMegabytes * 1024 * 1024
     val cacheDir = File(context.cacheDir, "volleyCache")
     val cache = DiskBasedCache(cacheDir, cacheSizeInBytes)
    
     val httpStack = HurlStack()
     val networkStack = BasicNetwork(httpStack)
    
     val queue = RequestQueue(cache, networkStack)
     queue.start()
    

    Then just use the queue and make sure to have request.setShouldCache(true) (or not).

    0 讨论(0)
  • 2020-12-09 19:12

    A very rude way but it works :)

    package it.dataware.passaeprendi.app.util;
    
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.os.Environment;
    import android.util.LruCache;
    
    import com.android.volley.VolleyLog;
    import com.android.volley.toolbox.ImageLoader;
    
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.util.Date;
    
    // https://stackoverflow.com/questions/14053338/save-bitmap-in-android-as-jpeg-in-external-storage-in-a-folder
    // https://stackoverflow.com/questions/8710515/reading-an-image-file-into-bitmap-from-sdcard-why-am-i-getting-a-nullpointerexc
    
    public class DiskBitmapCache implements ImageLoader.ImageCache {
    private File   cacheDir;
    
    // ...
    private  static final String CACHE_PATH      = "dataware/passaeprendi/imagechache/";
    private  static final String CACHE_FULL_PATH = Environment.getExternalStorageDirectory() + "/" + CACHE_PATH;
    private  static final int    MAX_IMAGE_AGE   = 5; // in days
    
    private  static final BitmapFactory.Options options = new BitmapFactory.Options();
    static {
    options.inPreferredConfig = Bitmap.Config.ARGB_8888;
    }
    
    public DiskBitmapCache() {
        cacheDir = new File(CACHE_FULL_PATH);
        cacheDir.mkdirs();
    }
    
    private static  ImageLoader.ImageCache imageLoaderCache = new ImageLoader.ImageCache() {
        private final LruCache<String, Bitmap> mCache = new LruCache<>(30);
    
        public void putBitmap(String url, Bitmap bitmap) {
            mCache.put(url, bitmap);
        }
        public Bitmap getBitmap(String url) {
            return mCache.get(url);
        }
    };
    
    public Bitmap getBitmap(String url) {
    
        final String volleyFileName = getFilenameForKey(url);
    
        final Bitmap bitmapL1 = imageLoaderCache.getBitmap(volleyFileName);
        if (bitmapL1 != null) {
            // VolleyLog.d("taken from cache L1 :" + url + " -> " + volleyFileName + ".");
            return bitmapL1;
        }
    
        final File volleyCacheFile = new File(cacheDir, volleyFileName);
    
        if (!volleyCacheFile.exists()) {
            return null;
        }
    
        // =======================================
        // age check
        // =======================================
    
        long diff = new Date().getTime() - volleyCacheFile.lastModified();
    
        if (diff > MAX_IMAGE_AGE * 24 * 60 * 60 * 1000) {
            volleyCacheFile.delete();
            return null;
        }
    
        // =======================================
        // load from disk
        // =======================================
    
        Bitmap bitmap = BitmapFactory.decodeFile(volleyCacheFile.getAbsolutePath(), options);
    
        if (bitmap != null) {
            //     VolleyLog.d("taken from cache L2 :" + url + " -> " + volleyFileName + ".");
            imageLoaderCache.putBitmap(volleyFileName, bitmap);
        }
    
        // VolleyLog.d("taken from cache L2 :" + url + " -> " + volleyFileName + ".");
        return bitmap;
    }
    
    public void putBitmap(String url, Bitmap bitmap) {
        final String volleyFileName = getFilenameForKey(url);
    
        File volleyCacheFile = new File(cacheDir, volleyFileName);
    
        try {
            // ...
            FileOutputStream fos = null;
            volleyCacheFile.createNewFile();
            fos = new FileOutputStream(volleyCacheFile, false);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
            fos.flush();
            fos.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    // Volley creates a filename for the url with the following function, so we'll use the same function
    // for translating the url back to said filename
    private String getFilenameForKey(String key) {
        int firstHalfLength = key.length() / 2;
    
        // ..
        String  localFilename   = String.valueOf(key.substring(0, firstHalfLength)  .hashCode());
                localFilename  += String.valueOf(key.substring(firstHalfLength)     .hashCode());
                localFilename  += ".jpg";
    
        return localFilename;
    }
    }    
    

    I hope will help someone.

    0 讨论(0)
  • 2020-12-09 19:15

    Consider using Glide which android recommends for loading images in your app. Compared to volley, Glide provides automatic image caching.

    To add Glide in your app:

    Step 1 ) Update build.gradle file

    dependencies {
        compile 'com.github.bumptech.glide:glide:3.6.1'
        compile 'com.android.support:support-v4:19.1.0'
      }
    

    Step 2) Add INTERNET permission in manifest file

    <uses-permission android:name="android.permission.INTERNET" />
    

    Step 3) Add ImageView in you layout

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/imageView"
        >
    </ImageView>
    

    Step 4) Glide Usage in Activity

        //Initialize ImageView
        ImageView imageView = (ImageView) findViewById(R.id.imageView);
    
        //Loading image from below url into imageView
       Glide.with(this)
            .load("IMAGE URL HERE")
            .placeholder(R.drawable.placeholder)
            .error(R.drawable.imagenotfound)
            .override(200, 200);
            .centerCrop();
            .into(imageView);
    

    Read more on Android Glide Library

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