J'utilise Picasso pour afficher des images dans mon application 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);
}
J'ai activé le débogage et il montre toujours soit le rouge et le vert. Mais ne montre jamais le jaune
Maintenant, si je charge la même image la prochaine fois et Internet n'est pas disponible, l'image n'est pas chargée.
Des questions:
C'est ce que j'ai fait. Fonctionne bien.
Commencez par ajouter OkHttp au fichier de construction Gradle du module d'application:
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'
Faites ensuite un cours qui étend 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);
}
}
ajoutez-le au fichier Manifest comme suit:
<application
Android:name=".Global"
.. >
</application>
Maintenant, utilisez Picasso comme vous le feriez normalement. Aucun changement.
MODIFIER:
si vous souhaitez utiliser uniquement les images en cache. Appelez la bibliothèque comme ça. J'ai remarqué que si nous n'ajoutons pas networkPolicy, les images ne s'afficheront pas dans un démarrage totalement hors ligne même si elles sont mises en cache . Le code ci-dessous résout le problème.
Picasso.with(this)
.load(url)
.networkPolicy(NetworkPolicy.OFFLINE)
.into(imageView);
EDIT # 2
le problème avec le code ci-dessus est que si vous effacez le cache, Picasso continuera à le rechercher hors ligne dans le cache et échouera. L'exemple de code suivant examine le cache local. S'il n'est pas trouvé hors connexion, il passe en ligne et reconstitue le cache.
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");
}
});
}
});
Pour la mise en cache, je voudrais utiliser OkHttp interceptors pour prendre le contrôle de la politique de mise en cache. Découvrez cet exemple inclus dans la bibliothèque OkHttp.
Voici comment je l'utiliserais avec 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 a par défaut un cache (voir la réponse de ahmed hamdy)
2) Si vous devez vraiment prendre l’image du cache disque puis du réseau, je vous recommande d’écrire votre propre téléchargeur:
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;
}
}
}
Et dans Application singleton dans la méthode OnCreate, utilisez-le avec 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) Aucune autorisation requise pour le dossier de cache de l'application defalut
Pour la version la plus récente, 2.71828, voici votre réponse.
Q1: N'a-t-il pas de cache disque local?
A1: Il y a une mise en cache par défaut dans Picasso et le flux de demandes est comme celui-ci.
App -> Memory -> Disk -> Server
Partout où ils ont rencontré leur image en premier, ils utiliseront cette image puis arrêteront le flux de demandes. Qu'en est-il du flux de réponse? Ne t'inquiète pas, la voici.
Server -> Disk -> Memory -> App
Par défaut, ils vont d'abord stocker sur un disque local pour le cache de conservation étendu. Ensuite, la mémoire, pour l'utilisation d'instance du cache.
Vous pouvez utiliser l'indicateur intégré dans Picasso pour voir où les images se forment en l'activant.
Picasso.get().setIndicatorEnabled(true);
Un drapeau apparaîtra dans le coin supérieur gauche de vos photos.
Q2: Comment puis-je activer la mise en cache du disque car j'utiliserai la même image plusieurs fois?
A2: Vous n'êtes pas obligé de l'activer. C'est le défaut.
Ce que vous devez faire, c'est DISABLE lorsque vous voulez que vos images soient toujours fraîches. Il y a 2 sens de la mise en cache désactivée.
.memoryPolicy()
sur NO_CACHE et/ou NO_STORE et le flux va ressembler à ceci.NO_CACHE ignorera la recherche d'images de la mémoire.
App -> Disk -> Server
NO_STORE ignorera les images stockées en mémoire lors du premier chargement d'images.
Server -> Disk -> App
.networkPolicy()
sur NO_CACHE et/ou NO_STORE et le flux va ressembler à ceci.NO_CACHE ignorera la recherche d'images à partir du disque.
App -> Memory -> Server
NO_STORE ignorera les images stockées sur le disque lors du premier chargement d'images.
Server -> Memory -> App
Vous pouvez DISABLE ni pour l'absence totale d'images en cache. Voici un exemple.
Picasso.get().load(imageUrl)
.memoryPolicy(MemoryPolicy.NO_CACHE,MemoryPolicy.NO_STORE)
.networkPolicy(NetworkPolicy.NO_CACHE, NetworkPolicy.NO_STORE)
.fit().into(banner);
Le flux de l'absence totale de cache et de stockage ressemblera à ceci.
App -> Server //Request
Server -> App //Response
Ainsi, vous aurez peut-être besoin de cela pour réduire également l'utilisation de votre stockage d'application.
Q: Dois-je ajouter une autorisation de disque au fichier manifeste Android?
A: Non, mais n'oubliez pas d'ajouter l'autorisation INTERNET pour votre requête HTTP.
J'utilise ce code et travaille, peut-être utile pour vous:
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...");
}
});
}
});
}
Ajoutez le code suivant dans Application.onCreate
puis utilisez-le normalement
Picasso picasso = new Picasso.Builder(context)
.downloader(new OkHttp3Downloader(this,Integer.MAX_VALUE))
.build();
picasso.setIndicatorsEnabled(true);
picasso.setLoggingEnabled(true);
Picasso.setSingletonInstance(picasso);
Si vous mettez d'abord les images en cache, faites quelque chose comme ceci dans 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);
}
et chargez vos images comme d'habitude ou avec la mise en cache disque
Picasso.with(this).load(Constants.imagesUrl+batterProduct.getGalleryImage())
.networkPolicy(NetworkPolicy.OFFLINE)
.placeholder(R.drawable.GalleryDefaultImage)
.error(R.drawable.GalleryDefaultImage)
.into(viewGallery);
Remarque:
Rouge couleur indique que l'image est extraite de réseau .
Vert couleur indique que l'image est extraite de mémoire cache .
Bleu couleur indique que l'image est extraite de mémoire de disque .
Avant de publier l'application, supprimez-la ou définissez-la false
picasso.setLoggingEnabled(true);
, picasso.setIndicatorsEnabled(true);
si non requis. Thankx