我正在使用Picasso在我的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); }
我已启用调试,它始终显示红色和绿色.但从不显示黄色
现在,如果我下次加载相同的图像并且互联网不可用,则不会加载图像.
问题:
它没有本地磁盘缓存吗?
如何启用磁盘缓存,因为我将多次使用相同的图像.
我需要为android清单文件添加一些磁盘权限吗?
Sanket Berde.. 226
这就是我做的.效果很好.
首先将OkHttp添加到app模块的gradle构建文件中:
compile 'com.squareup.picasso:picasso:2.5.2' compile 'com.squareup.okhttp3:okhttp:3.10.0' compile 'com.jakewharton.picasso:picasso2-okhttp3-downloader:1.1.0'
然后进行课程扩展 Application
import android.app.Application; import com.jakewharton.picasso.OkHttp3Downloader; 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 OkHttp3Downloader(this,Integer.MAX_VALUE)); Picasso built = builder.build(); built.setIndicatorsEnabled(true); built.setLoggingEnabled(true); Picasso.setSingletonInstance(built); } }
将它添加到Manifest文件,如下所示:
现在像往常一样使用毕加索.没有变化.
编辑:
如果您只想使用缓存图像.像这样调用库.我注意到,如果我们不添加networkPolicy,即使缓存它们,图像也不会在完全脱机启动时显示.下面的代码解决了这个问题.
Picasso.with(this) .load(url) .networkPolicy(NetworkPolicy.OFFLINE) .into(imageView);
编辑#2
上面代码的问题在于,如果清除缓存,Picasso将继续在缓存中脱机查找并失败,下面的代码示例查看本地缓存,如果未找到脱机,它将联机并补充缓存.
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"); } }); } });
@SanketBerde:感谢快速注释,但我发现只有当应用程序在后台运行时(离线时),图像才会从内存中传出.如果我关闭应用程序,那么运行的应用程序很清楚,然后再次打开我的应用程序,图像不会从缓存中加载.我已设置即将出现的错误默认加载图像.这可能有什么问题? (4认同)
谢谢它的工作.为什么它不是公认的答案? (2认同)
ahmed hamdy.. 45
1)第一个问题的答案:根据Picasso Doc for With()方法
从with()返回的全局默认Picasso实例使用适合大多数实现的默认值自动初始化.
LRU内存缓存可用应用程序RAM的15%
2%存储空间的磁盘缓存高达50MB但不低于5MB.
但 Disk Cache
全球默认毕加索的操作仅适用于API 14+
2)第二个问题的答案是:Picasso
使用HTTP
客户端请求Disk Cache
的操作所以你可以使自己http request header
拥有产权Cache-Control
与max-age
开创自己的静态毕加索实例,而不是默认的毕加索通过使用
1] HttpResponseCache(注意:仅适用于API 13+)
2] OkHttpClient(适用于所有API)
用于OkHttpClient
创建自己的Static Picasso类的示例:
首先创建一个新类来获取自己的单例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)回答第三个问题:磁盘缓存操作不需要任何磁盘权限
参考文献:关于磁盘缓存的Github问题,@ jake-wharton已经回答了两个问题- > 问题1和问题2
这就是我做的.效果很好.
首先将OkHttp添加到app模块的gradle构建文件中:
compile 'com.squareup.picasso:picasso:2.5.2' compile 'com.squareup.okhttp3:okhttp:3.10.0' compile 'com.jakewharton.picasso:picasso2-okhttp3-downloader:1.1.0'
然后进行课程扩展 Application
import android.app.Application; import com.jakewharton.picasso.OkHttp3Downloader; 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 OkHttp3Downloader(this,Integer.MAX_VALUE)); Picasso built = builder.build(); built.setIndicatorsEnabled(true); built.setLoggingEnabled(true); Picasso.setSingletonInstance(built); } }
将它添加到Manifest文件,如下所示:
<application android:name=".Global" .. > </application>
现在像往常一样使用毕加索.没有变化.
编辑:
如果您只想使用缓存图像.像这样调用库.我注意到,如果我们不添加networkPolicy,即使缓存它们,图像也不会在完全脱机启动时显示.下面的代码解决了这个问题.
Picasso.with(this) .load(url) .networkPolicy(NetworkPolicy.OFFLINE) .into(imageView);
编辑#2
上面代码的问题在于,如果清除缓存,Picasso将继续在缓存中脱机查找并失败,下面的代码示例查看本地缓存,如果未找到脱机,它将联机并补充缓存.
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"); } }); } });
对于缓存,我会使用OkHttp 拦截器来控制缓存策略.查看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)Picasso默认有缓存(见ahmed hamdy的答案)
2)如果您真的必须从磁盘缓存然后网络中获取图像,我建议您编写自己的下载器:
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方法将它与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)defalut应用程序缓存文件夹不需要权限
1)第一个问题的答案:根据Picasso Doc for With()方法
从with()返回的全局默认Picasso实例使用适合大多数实现的默认值自动初始化.
LRU内存缓存可用应用程序RAM的15%
2%存储空间的磁盘缓存高达50MB但不低于5MB.
但 Disk Cache
全球默认毕加索的操作仅适用于API 14+
2)第二个问题的答案是:Picasso
使用HTTP
客户端请求Disk Cache
的操作所以你可以使自己http request header
拥有产权Cache-Control
与max-age
开创自己的静态毕加索实例,而不是默认的毕加索通过使用
1] HttpResponseCache(注意:仅适用于API 13+)
2] OkHttpClient(适用于所有API)
用于OkHttpClient
创建自己的Static Picasso类的示例:
首先创建一个新类来获取自己的单例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)回答第三个问题:磁盘缓存操作不需要任何磁盘权限
参考文献:关于磁盘缓存的Github问题,@ jake-wharton已经回答了两个问题- > 问题1和问题2