如何在毕加索中使用磁盘caching?

我正在使用毕加索在我的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); } 

我已经启用debugging,它总是显示红色和绿色,但从不显示黄色

现在,如果我下次加载相同的图像和互联网不可用的图像不加载。

问题:

  1. 它没有本地磁盘caching吗?
  2. 我如何启用磁盘caching,因为我将多次使用相同的图像。
  3. 我需要添加一些磁盘权限到Android清单文件?

这就是我所做的。 效果很好

首先将OkHttp添加到app模块的gradle构build文件中

 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' 

然后创build一个类扩展应用程序

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

将其添加到清单文件如下所示:

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

像平时一样使用毕加索。 没有变化。

编辑:

如果你只想使用caching的图像。 像这样调用库。 我注意到,如果我们不添加networkPolicy, 即使它们被caching图像也不会在完全离线的启动中显示出来 。 下面的代码解决了这个问题。

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

编辑#2

上面的代码的问题是,如果你清除caching,毕加索将继续在caching中查找它,并失败,下面的代码示例查看本地caching,如果没有发现离线,它将联机并补充caching。

 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)第一个问题的答案:根据Picasso Doc for With()方法

从()返回的全局默认Picasso实例会自动初始化,其默认值适用于大多数实现。

  • LRU内存caching的15%是可用的应用程序RAM
  • 2%存储空间的磁盘caching高达50MB但不低于5MB。

全局默认毕加索的Disk Cache操作仅适用于API 14+

2)回答第二个问题: Picasso使用HTTP客户端请求进行Disk Cache操作所以你可以让你自己的http request header有属性Cache-Controlmax-age创build你自己的静态毕加索实例而不是默认的毕加索通过使用

1] HttpResponseCache (注意:仅适用于API 13+)
2] OkHttpClient (适用于所有的API)

使用OkHttpClient创build您自己的Static Picasso类的示例

  • 首先创build一个新的类来获得你自己的单身picasso对象

     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; } } 
  • 使用你自己的单身picasso对象而不是Picasso.With()

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

3)回答第三个问题:磁盘Cache操作不需要任何磁盘权限

参考文献 : 关于磁盘caching的Github问题 ,已经通过@ jake-wharton回答了两个问题 – > 问题1和问题2

为了caching,我会使用OkHttp 拦截器来控制caching策略。 看看这个包含在OkHttp库中的示例。

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

下面是我将如何使用毕加索 –

 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)毕加索默认已经caching(详见ahmed hamdy answer)

2)如果你真的必须从磁盘caching,然后networking形象,我build议编写自己的下载:

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

而在OnCreate方法中的单身人士使用它与毕加索:

  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)defalut应用程序caching文件夹不需要权限

我使用这个代码,工作,也许对你有用:

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

Application.onCreate添加followning代码,然后使用它正常

  Picasso picasso = new Picasso.Builder(context) .downloader(new OkHttp3Downloader(this,Integer.MAX_VALUE)) .build(); picasso.setIndicatorsEnabled(true); picasso.setLoggingEnabled(true); Picasso.setSingletonInstance(picasso); 

如果你先caching图像,然后在ProductImageDownloader.doBackground做这样的事情

 final Callback callback = new Callback() { @Override public void onSuccess() { downLatch.countDown(); updateProgress(); } @Override public void onError() { errorCount++; downLatch.countDown(); updateProgress(); } }; Picasso.with(context).load(Constants.imagesUrl+productModel.getGalleryImage()) .memoryPolicy(MemoryPolicy.NO_CACHE).fetch(callback); Picasso.with(context).load(Constants.imagesUrl+productModel.getLeftImage()) .memoryPolicy(MemoryPolicy.NO_CACHE).fetch(callback); Picasso.with(context).load(Constants.imagesUrl+productModel.getRightImage()) .memoryPolicy(MemoryPolicy.NO_CACHE).fetch(callback); try { downLatch.await(); } catch (InterruptedException e) { e.printStackTrace(); } if(errorCount == 0){ products.remove(productModel); productModel.isDownloaded = true; productsDatasource.updateElseInsert(productModel); }else { //error occurred while downloading images for this product //ignore error for now // FIXME: 9/27/2017 handle error products.remove(productModel); } errorCount = 0; downLatch = new CountDownLatch(3); if(!products.isEmpty() /*&& testCount++ < 30*/){ startDownloading(products.get(0)); }else { //all products with images are downloaded publishProgress(100); } 

并像正常或磁盘caching加载您的图像

  Picasso.with(this).load(Constants.imagesUrl+batterProduct.getGalleryImage()) .networkPolicy(NetworkPolicy.OFFLINE) .placeholder(R.drawable.GalleryDefaultImage) .error(R.drawable.GalleryDefaultImage) .into(viewGallery); 

注意:

红色表示图像是从networking获取的。

绿色表示图像是从高速缓冲存储器中取出的。

蓝色表示图像是从磁盘存储器中获取的。

在释放应用程序之前删除或设置它为false picasso.setLoggingEnabled(true);picasso.setIndicatorsEnabled(true); 如果不是必需的。 Thankx