¿Cómo configuro correctamente Volley para descargar imágenes desde una URL

Sé que Volley se supone que hacer la descarga y almacenamiento en caché de imágenes sin sentido simple pero todavía he estado luchando por horas para implementarlo correctamente. He mirado alrededor de la red, así como los muchos artículos sobre stackoverflow con respecto a volea, pero ninguno de los ejemplos que he encontrado parecen funcionar para mí.

Sólo quiero usar volley para descargar y almacenar en caché las imágenes de una url determinada, no para hacer ninguna manipulación de HTTP JSON REST. Sólo para tomar urls determinado, descargar los mapas de bits y establecerlos a la vista de la imagen y luego agregarlos a la caché.

Este ha sido mi último intento hasta ahora. ¿Cómo carga y cacheo las imágenes con volley correctamente?

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; } 

Cuando ejecuto esto obtengo una NullPointerException apuntando a esta línea

 Cache cache = ImgController.getInstance().getRequestQueue().getCache(); 

He configurado la siguiente clase singleton para manejar las solicitudes

 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í como la siguiente clase LruBitmapCache

 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); } 

}

(Lo siento por la mala habilidad inglesa ^^;)

Volley se supone que hacer la descarga y almacenamiento en caché de imágenes sin sentido simple

¡SÍ! Volley es MUY SIMPLE. Usted no necesita pensar en golpe de caché, carga de imágenes, etc …

Sólo use NetworkImageView . Belows son ejemplo.

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 carga automáticamente la imagen de la cola de fondo y cancela la solicitud cuando esta vista se separa using ImageLoader . Y ImageLoader utiliza automáticamente caché de memoria lru y caché de disco. NetworkImageView es la mejor solución para usted.

Información Adicional

 NetworkImageView | ImageLoader (uses `LruBitmapCache` you implemented.) | RequestQueue (uses `DiskBasedCache`. it is already implemented in volley.) 

Una llamada de retorno para Solicitud de imagen está disponible para Volley, puede utilizar el siguiente código a continuación.

  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); 

ImageRequest está obsoleto por lo que lo estoy haciendo de la siguiente manera:

Paso 1: Haga que la clase Application sea ​​la siguiente

 public class YourApplicationClass extends Application { private static YourApplicationClass sInstance; private RequestQueue mRequestQueue; private ImageLoader mImageLoader; public static YourApplicationClass getInstance(){ return sInstance; } @Override public void onCreate() { super.onCreate(); sInstance = this; mRequestQueue = Volley.newRequestQueue(this); mImageLoader = new ImageLoader(this.mRequestQueue, new ImageLoader.ImageCache() { private final LruCache<String, Bitmap> mCache = new LruCache<String, Bitmap>(10); public Bitmap getBitmap(String url) { return mCache.get(url); } @Override public void putBitmap(String url, Bitmap bitmap) { mCache.put(url, bitmap); } }); } public RequestQueue getRequestQueue(){ return mRequestQueue; } public ImageLoader getImageLoader(){ return mImageLoader; } } 

Paso 2: Ahora haga una petición de imagen como sigue de cualquier actividad o fragmento

 YourApplicationClass.getInstance().getImageLoader().get(image_url, new ImageLoader.ImageListener() { @Override public void onResponse(ImageLoader.ImageContainer imageContainer, boolean b) { Bitmap bitmap = imageContainer.getBitmap(); //use bitmap } @Override public void onErrorResponse(VolleyError volleyError) { } }); 

Tengo una solución más simple para mostrar la imagen de url y almacenarla en caché. Sin agregar clases adicionales, sólo MainActivity. Probablemente ayudará a alguien …

Aquí está mi XML que muestra sólo ImageView

 <?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout 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" tools:context="com.example.natalie.volley.MainActivity"> <ImageView android:id="@+id/ivImageView" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="50dp"/> </android.support.constraint.ConstraintLayout> 

Y aquí está mi MainAvtivity.java:

  import android.graphics.Bitmap; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.widget.ImageView; import com.android.volley.RequestQueue; import com.android.volley.Response; import com.android.volley.VolleyError; import com.android.volley.toolbox.ImageRequest; import com.android.volley.toolbox.Volley; public class MainActivity extends AppCompatActivity { private String url = "http://kingofwallpapers.com/picture/picture-010.jpg"; ImageView ivImageView; RequestQueue mRequestQueue; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ivImageView = (ImageView)findViewById(R.id.ivImageView); mRequestQueue = Volley.newRequestQueue(this.getApplicationContext()); ImageRequest imageRequest = new ImageRequest(url, new BitmapListener(), 0, 0, null, null, new MyErrorListener()); mRequestQueue.add(imageRequest); } private class BitmapListener implements Response.Listener<Bitmap> { @Override public void onResponse(Bitmap response) { // response = your url's bitmap ivImageView.setImageBitmap(response); } } private class MyErrorListener implements Response.ErrorListener { @Override public void onErrorResponse(VolleyError error) { //store a default image if connection failed ivImageView.setImageResource(R.drawable.error_icon); } } } 

No olvides añadir <uses-permission android:name="android.permission.INTERNET" /> en Manifest.xml y compile 'com.android.volley:volley:1.0.0' en las dependencias de build.gradle

  • Invalidar caché en Picasso
  • OkHttp3 caché parece estar desmarcada con Retrofit 2
  • Android: Viewpager y FragmentStatePageAdapter
  • Almacenamiento en caché de los datos descargados de JSON en la base de datos SQLite - ¿es una buena idea?
  • Mejores opciones que backporting ICS HttpResponseCache
  • Necesito descargar varias imágenes al directorio para poder acceder al contenido sin conexión
  • If-None-Match no se pasa en mi solicitud
  • Picasso caché con diferentes transformaciones aplicadas
  • ¿Cómo integrar Google Drive con Picasso en Android?
  • ViewPager + FragmentStatePagerAdapter + cambio de orientación
  • Las imágenes se cargan más rápido en la vista web
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.