¿Cómo uso la caché de disco en Picasso?

Estoy usando Picasso para mostrar la imagen en mi aplicación para Android:

/** * load image.This is within a activity so this context is activity */ public void loadImage (){ Picasso picasso = Picasso.with(this); picasso.setDebugging(true); picasso.load(quiz.getImageUrl()).into(quizImage); } 

Tengo habilitar la depuración y siempre muestra rojo o verde. Pero nunca muestra amarillo

Ahora si carga la misma imagen la vez próxima e internet no está disponible la imagen no se carga.

Preguntas:

  1. ¿No tiene caché de disco local?
  2. ¿Cómo puedo habilitar la caché de disco como voy a utilizar la misma imagen varias veces.
  3. ¿Necesito añadir algún permiso de disco al archivo de manifiesto de android?

Esto es lo que hice. Funciona bien

Primero agregue el OkHttp al archivo de compilación gradle del módulo de la aplicación

 compile 'com.squareup.picasso:picasso:2.5.2' compile 'com.squareup.okhttp:okhttp:2.4.0' compile 'com.jakewharton.picasso:picasso2-okhttp3-downloader:1.0.2' 

Luego haga una clase extendiendo la Aplicación

 import android.app.Application; import com.squareup.picasso.OkHttpDownloader; import com.squareup.picasso.Picasso; public class Global extends Application { @Override public void onCreate() { super.onCreate(); Picasso.Builder builder = new Picasso.Builder(this); builder.downloader(new OkHttpDownloader(this,Integer.MAX_VALUE)); Picasso built = builder.build(); built.setIndicatorsEnabled(true); built.setLoggingEnabled(true); Picasso.setSingletonInstance(built); } } 

Agregue al archivo del manifiesto como sigue:

 <application android:name=".Global" .. > </application> 

Ahora usa Picasso como lo harías normalmente. Sin cambios.

EDITAR:

Si desea utilizar sólo imágenes almacenadas en caché. Llame a la biblioteca así. He notado que si no agregamos el networkPolicy, las imágenes no se mostrarán en un inicio totalmente sin conexión incluso si se almacenan en caché . El código siguiente resuelve el problema.

 Picasso.with(this) .load(url) .networkPolicy(NetworkPolicy.OFFLINE) .into(imageView); 

EDIT # 2

El problema con el código anterior es que si se borra la memoria caché, Picasso seguirá buscando fuera de línea en caché y fallar, el ejemplo de código siguiente busca en la caché local, si no se encuentra fuera de línea, se vuelve a conectar y vuelve a llenar la caché.

 Picasso.with(getActivity()) .load(imageUrl) .networkPolicy(NetworkPolicy.OFFLINE) .into(imageView, new Callback() { @Override public void onSuccess() { } @Override public void onError() { //Try again online if cache failed Picasso.with(getActivity()) .load(posts.get(position).getImageUrl()) .error(R.drawable.header) .into(imageView, new Callback() { @Override public void onSuccess() { } @Override public void onError() { Log.v("Picasso","Could not fetch image"); } }); } }); 

1) respuesta de la primera pregunta: según Picasso Doc para With () método

La instancia global predeterminada de Picasso devuelta desde with () se inicializa automáticamente con valores predeterminados que son adecuados para la mayoría de las implementaciones.

  • Caché de memoria LRU del 15% de la RAM de la aplicación disponible
  • Caché de disco de 2% de espacio de almacenamiento de hasta 50 MB, pero no menos de 5 MB.

Pero la operación de Disk Cache para el valor predeterminado global de Picasso sólo está disponible en API 14+

2) Respuesta de la segunda Pregunta: Picasso utiliza la solicitud de cliente HTTP a la operación de Disk Cache Así que puede hacer su propia http request header tiene la propiedad Cache-Control con max-age Y crear su propia instancia de Picasso estático en lugar de Picasso predeterminado Utilizando

1] HttpResponseCache (Nota: funciona sólo para API 13+)
2] OkHttpClient (Works para todas las API)

Ejemplo de uso de OkHttpClient para crear su propia clase Static Picasso:

  • Primero crea una nueva clase para obtener tu propio objeto picasso singleton

     import android.content.Context; import com.squareup.picasso.Downloader; import com.squareup.picasso.OkHttpDownloader; import com.squareup.picasso.Picasso; public class PicassoCache { /** * Static Picasso Instance */ private static Picasso picassoInstance = null; /** * PicassoCache Constructor * * @param context application Context */ private PicassoCache (Context context) { Downloader downloader = new OkHttpDownloader(context, Integer.MAX_VALUE); Picasso.Builder builder = new Picasso.Builder(context); builder.downloader(downloader); picassoInstance = builder.build(); } /** * Get Singleton Picasso Instance * * @param context application Context * @return Picasso instance */ public static Picasso getPicassoInstance (Context context) { if (picassoInstance == null) { new PicassoCache(context); return picassoInstance; } return picassoInstance; } } 
  • Utilice su propio objeto picasso singleton En lugar de Picasso.With()

PicassoCache.getPicassoInstance(getContext()).load(imagePath).into(imageView)

3) respuesta para la tercera pregunta: no necesita ningún permiso de disco para operaciones de caché de disco

Referencias : Github cuestión sobre la caché de disco , dos preguntas ha sido respondida por @ jake-wharton -> Pregunta1 y Pregunta2

Para el almacenamiento en caché, utilizaría los interceptores OkHttp para obtener el control sobre la política de almacenamiento en caché. Echa un vistazo a este ejemplo que está incluido en la biblioteca OkHttp.

https://github.com/square/okhttp/blob/master/samples/guide/src/main/java/com/squareup/okhttp/recipes/RewriteResponseCacheControl.java

Aquí es cómo lo utilizaría con Picasso –

 OkHttpClient okHttpClient = new OkHttpClient(); okHttpClient.networkInterceptors().add(new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Response originalResponse = chain.proceed(chain.request()); return originalResponse.newBuilder().header("Cache-Control", "max-age=" + (60 * 60 * 24 * 365)).build(); } }); okHttpClient.setCache(new Cache(mainActivity.getCacheDir(), Integer.MAX_VALUE)); OkHttpDownloader okHttpDownloader = new OkHttpDownloader(okHttpClient); Picasso picasso = new Picasso.Builder(mainActivity).downloader(okHttpDownloader).build(); picasso.load(imageURL).into(viewHolder.image); 

1) Picasso por defecto tiene caché (véase ahmed hamdy respuesta)

2) Si su realmente debe tomar la imagen del escondrijo del disco y entonces red Recomiendo escribir su propio downloader:

 public class OkHttpDownloaderDiskCacheFirst extends OkHttpDownloader { public OkHttpDownloaderDiskCacheFirst(OkHttpClient client) { super(client); } @Override public Response load(Uri uri, int networkPolicy) throws IOException { Response responseDiskCache = null; try { responseDiskCache = super.load(uri, 1 << 2); //NetworkPolicy.OFFLINE } catch (Exception ignored){} // ignore, handle null later if (responseDiskCache == null || responseDiskCache.getContentLength()<=0){ return super.load(uri, networkPolicy); //user normal policy } else { return responseDiskCache; } } } 

Y en Singleton aplicación en el método OnCreate utilizarlo con picasso:

  OkHttpClient okHttpClient = new OkHttpClient(); okHttpClient.setCache(new Cache(getCacheDir(), 100 * 1024 * 1024)); //100 MB cache, use Integer.MAX_VALUE if it is too low OkHttpDownloader downloader = new OkHttpDownloaderDiskCacheFirst(okHttpClient); Picasso.Builder builder = new Picasso.Builder(this); builder.downloader(downloader); Picasso built = builder.build(); Picasso.setSingletonInstance(built); 

3) No se necesitan permisos para la carpeta de caché de aplicaciones defalut

Yo uso este código y funcionó, tal vez útil para usted:

 public static void makeImageRequest(final View parentView,final int id, final String imageUrl) { final int defaultImageResId = R.mipmap.user; final ImageView imageView = (ImageView) parentView.findViewById(id); Picasso.with(context) .load(imageUrl) .networkPolicy(NetworkPolicy.OFFLINE) .into(imageView, new Callback() { @Override public void onSuccess() { Log.v("Picasso","fetch image success in first time."); } @Override public void onError() { //Try again online if cache failed Log.v("Picasso","Could not fetch image in first time..."); Picasso.with(context).load(imageUrl).networkPolicy(NetworkPolicy.NO_CACHE) .memoryPolicy(MemoryPolicy.NO_CACHE, MemoryPolicy.NO_STORE).error(defaultImageResId) .into(imageView, new Callback() { @Override public void onSuccess() { Log.v("Picasso","fetch image success in try again."); } @Override public void onError() { Log.v("Picasso","Could not fetch image again..."); } }); } }); } 
  • Picasso Imagen para Android cargando - modelo de hilo
  • ¿Cómo hacer deslizar la pantalla como picasso?
  • Image uri no muestra imágenes en ImageView en algún dispositivo Android
  • Picasso y contexto
  • El objetivo no debe ser nulo utilizando la Biblioteca Picasso
  • Invalidar caché en Picasso
  • Picasso: cargar imágenes en widget listview
  • Picasso problema de extracción de imágenes cuando se utiliza con RecyclerView
  • Descargar y guardar imágenes con Picasso
  • Glide - carga un solo fotograma del video en un momento específico?
  • Preload de imágenes en la memoria / disco con Android Picasso
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.