I know Volley is supposed to make downloading and caching images mindlessly simple but yet I have been struggling for hours to properly implement it. I've looked around the net as well as the many articles on stackoverflow regarding volley but none of the examples I've found seem to work for me.
I only want to use volley to download and cache images from a given url, not to do any HTTP JSON REST handling. Just to take given urls, download the bitmaps and set them to the imageview then add them to the cache.
This has been my latest attempt so far. How do I load and cache images with volley correctly?
if (data.getImageUrl() != null) {
try {
holder.thumbnail.setTag(data.getImageUrl());
Cache cache = ImgController.getInstance().getRequestQueue().getCache();
Cache.Entry entry = cache.get(data.getImageUrl());
if (entry != null) {
try {
String cImg = new String(entry.data, "UTF-8");
LruBitmapCache bitmapCache = new LruBitmapCache();
holder.thumbnail.setImageBitmap(bitmapCache.getBitmap(cImg));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
} else {
ImageLoader imageLoader = ImgController.getInstance().getImageLoader();
imageLoader.get(data.getImageUrl(), new ImageListener() {
@Override
public void onErrorResponse(VolleyError error) {
holder.thumbnail.setImageResource(R.drawable.filler_icon);
}
@Override
public void onResponse(ImageLoader.ImageContainer response, boolean arg1) {
if (response.getBitmap() != null) {
// load image into imageview
holder.thumbnail.setImageBitmap(response.getBitmap());
}
}
});
}
return convertView;
} catch (Exception e) {
e.printStackTrace();
Log.v(DEBUG_TAG, "no image: ", e);
holder.thumbnail.setImageResource(R.drawable.filler_icon);
}
}else {
return null;
}
return convertView;
}
When I run this I get a NullPointerException pointing to this line
Cache cache = ImgController.getInstance().getRequestQueue().getCache();
I've setup the following singleton class to handle requests
public class ImgController extends Application {
public static final String TAG = ImgController.class.getSimpleName();
private RequestQueue requestQueue;
private ImageLoader imageLoader;
private static ImgController instance;
@Override
public void onCreate() {
super.onCreate();
instance = this;
}
public static synchronized ImgController getInstance(){
return instance;
}
public RequestQueue getRequestQueue(){
if(requestQueue == null){
requestQueue = Volley.newRequestQueue(getApplicationContext());
}
return this.requestQueue;
}
public ImageLoader getImageLoader(){
getRequestQueue();
if(imageLoader == null){
imageLoader = new ImageLoader(this.requestQueue, new LruBitmapCache());
}
return this.imageLoader;
}
public <T> void addToRequestQueue(Request<T> req, String tag) {
// set the default tag if tag is empty
req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
getRequestQueue().add(req);
}
public <T> void addToRequestQueue(Request<T> req) {
req.setTag(TAG);
getRequestQueue().add(req);
}
public void cancelPendingRequests(Object tag) {
if (requestQueue != null) {
requestQueue.cancelAll(tag);
}
}
}
as well as the following LruBitmapCache class
public class LruBitmapCache extends LruCache<String, Bitmap> implements ImageLoader.ImageCache {
public static int getDefaultLruCacheSize(){
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
final int cacheSize = maxMemory / 8;
return cacheSize;
}
public LruBitmapCache() {
this(getDefaultLruCacheSize());
}
public LruBitmapCache(int maxSize) {
super(maxSize);
}
@Override
public Bitmap getBitmap(String url) {
return get(url);
}
@Override
public void putBitmap(String url, Bitmap bitmap) {
put (url, bitmap);
}
}
(Sorry for poor english skill ^^;)
Volley is supposed to make downloading and caching images mindlessly simple
YEAH! Volley is VERY SIMPLE. you don't need to think about cache hit, image loading etc...
just use NetworkImageView
. Belows are example.
layout_example.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".MainActivity">
<com.android.volley.toolbox.NetworkImageView
android:id="@+id/photo"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
MainActivity.java
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_example);
NetworkImageView nv = (NetworkImageView) findViewById(R.id.photo);
nv.setDefaultImageResId(R.drawable.default_image); // image for loading...
nv.setImageUrl(imageUrl, ImgController.getInstance().getImageLoader()); //ImgController from your code.
}
NetworkImageView
automatically loads image from background queue and cancel request when this view is detached using ImageLoader
. and ImageLoader
automatically uses memory lru cache and disk cache. NetworkImageView
is best solution for you.
NetworkImageView
|
ImageLoader (uses `LruBitmapCache` you implemented.)
|
RequestQueue (uses `DiskBasedCache`. it is already implemented in volley.)
A callback for Image Request is available for Volley, you can use the Following code below.
ImageView iv = null; /*Attach the Pointer for ImageView*/
RequestQueue requestAdministrator = null; /*Attach the Pointer for Volley*/
ImageRequest ir = new ImageRequest(url, new Response.Listener<Bitmap>() {
@Override
public void onResponse(Bitmap response) {
// callback
iv.setImageBitmap(response);
}
}, 100, 100, null, null);
// 100 is your custom Size before Downloading the Image.
requestAdministrator.add(ir);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With