I have a situation where I have to check if the user profile has changed. I am saving the URL in shared prefs if the shared prefs are empty for the first time. From then on every time I get a URL from intent I am downloading the image from shared preference, downloading the image from the intent and doing the sameAs method. I am wondering if there a better way of doing this? Can anyone suggest to me.
My suggest in your situation not to download Image , You Just need to cache it using
Glide or Picasso lib
Picasso.get()
.load(finalUrl)
.networkPolicy(NetworkPolicy.OFFLINE)
.fit()
.centerInside()
.placeholder(R.drawable.ic_placeholders)
.into(target, new Callback() {
#Override
public void onSuccess() {
}
#Override
public void onError(Exception e) {
Picasso.get()
.load(finalUrl1)
.placeholder(R.drawable.ic_placeholders)
.fit()
.centerInside()
.into(target);
}
});
so this check if your Images Is loaded in cache first
and if exist do not download it
.networkPolicy(NetworkPolicy.OFFLINE)
by this code
and if it not exist in cache , it will download it
Related
Am using Glide version 4.8.0
And for loading an image I do this
GlideApp
.with(HomePageFragment.this)
.load(remoteURL)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(mImageView);
When the device is connected to Internet the image loades successfully but when device goes offline, how to load the same image from cache that was already featched from the remoteURL?
My CustomAppGlideModule looks like this
#GlideModule
public class CustomAppGlideModule extends AppGlideModule {
#Override
public void applyOptions(#NonNull Context context, #NonNull GlideBuilder builder) {
builder.setMemoryCache(new LruResourceCache(20 * 1024 * 1024));
builder.setDiskCache(new InternalCacheDiskCacheFactory(context, 100 * 1024 * 1024));
}
}
I also tried
.onlyRetrieveFromCache(true)
But that also does not help.
Option 1:
Use DiskCacheStrategy.SOURCE instead of DiskCacheStrategy.ALL it should work because of DiskCacheStrategy.SOURCE saves the original data to cache.
//Version 4.x
GlideApp
.with(HomePageFragment.this)
.load(remoteURL)
.diskCacheStrategy(DiskCacheStrategy.DATA)
.into(mImageView);
//Version 3.x
Glide.with(mContext)
.load(url)
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
.into(imageView);
Option 2: (if above does not work)
Any specific reason for using Glide? Would you like to give a shot to Picasso, I found Picasso much better for this. You may use the following code for offline caching. It will first serve from offline if not found then search for online image.
Picasso.with(getActivity())
.load(imageUrl)
.networkPolicy(NetworkPolicy.OFFLINE)
.into(imageView, new Callback() {
#Override
public void onSuccess() {
//..image loaded from cache
}
#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() {
//... image loaded from online
}
#Override
public void onError() {
Log.v("Picasso","Could not fetch image");
}
});
}
});
I load image from URL using picasso first time on line, After then use from cache. Any URL from web is load in imageview on line or off line. But my server image URL is load image in on line not in off line. I use below code from image load.
Picasso.with(mContext)
.load(urlProfile)
.networkPolicy(NetworkPolicy.OFFLINE)
.placeholder(R.drawable.ic_place_holder)
.into(imageView, new Callback() {
#Override
public void onSuccess() {
}
#Override
public void onError() {
Picasso.with(mContext)
.load(urlProfile)
.placeholder(R.drawable.ic_place_holder)
.into(imageView);
}
});
Web url load in online or offline both : URL
My server url load image only in online: URL
I show in cache directory and found that image of my server URL is not cached. Any have idea about that.
Hi below is my solutions and it's working perfectlly.
Picasso.with(mContext)
.load(Uri.parse(urlProfile))
.networkPolicy(NetworkPolicy.OFFLINE)
.into(iv_view, new Callback() {
#Override
public void onSuccess() {
// if you are showing progress then handle it on here
}
#Override
public void onError() {
// Try again online if cache failed and download using internet
new Picasso.Builder(mContext)
.downloader(new OkHttpDownloader(mContext, Integer.MAX_VALUE))
.build()
.load(Uri.parse(urlProfile))
.placeholder(R.mipmap.ic_launcher)
.into(iv_view);
}
});
Hope this helps you..
By the way this is very old but you can use Glide for better performance.
I am using Picasso library to get Image from an url.
My problem is when I load an Image for the first time and I exit out of my app and after I come back my app tries to load the Image again but I don't want it happen. Are there any other way to do that(load just one time the Image and in others time don't need to Internet for load)?
The issue with the above answers is that they only check the availability of the images in the disk cache, it does not cover the part if the image does not exist in the cache to go online and retrieve it.
First make a class that extends Application (You can name it whatever you want that does not interfere with your application, my convention is to use "Global").
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(false);
built.setLoggingEnabled(true);
Picasso.setSingletonInstance(built);
}
}
Make sure you add dependancy for OkHttp library, it's developed by the same guys from Picasso
compile 'com.squareup.okhttp:okhttp:2.4.0'
and add the class in your Manifest file Applications tag :
android:name=".Global"
Then when you want to retrieve the image :
Picasso.with(context)
.load(Image URL)
.networkPolicy(NetworkPolicy.OFFLINE)
.into(imageView, new Callback() {
#Override
public void onSuccess() {
}
#Override
public void onError() {
//Try again online if cache failed
Picasso.with(context)
.load(Image URL)
.into(imageView, new Callback() {
#Override
public void onSuccess() {
}
#Override
public void onError() {
Log.v("Picasso","Could not fetch image");
}
});
}
});
The above method checks if the image is already cached, if not gets it from the internet.
try this:
Picasso.with(this).load(url).networkPolicy(NetworkPolicy.OFFLINE).into(imageView);
try this:
Picasso.with(this).invalidate(url);
Picasso.with(this)
.load(url)
.networkPolicy(
NetworkUtils.isConnected(this) ?
NetworkPolicy.NO_CACHE : NetworkPolicy.OFFLINE)
.resize(200, 200)
.centerCrop()
.placeholder(R.mipmap.ic_avatar)
.error(R.mipmap.ic_avatar)
.into(imageView);
I'm working on an application in which i use Picasso library for image loading in my ViewPager and other ImageViews. So i want to know what happens if network connectivity is off. Does the library handle itself or do i have to check the network connectivity before loading image to views?
My code:
Picasso picasso = Picasso.with(getActivity());
picasso.setDebugging(true);
picasso.load(downloadPath+imgDetailPhoto)
.placeholder(R.drawable.no_image)
.error(android.R.drawable.stat_notify_error)
.into(eventImage, new Callback() {
#Override
public void onSuccess() {
Log.d("Success...", "picasso loaded successfully");
}
#Override
public void onError() {
Log.d("Error...", "picasso load error");
}
});
Using below code Picasso caches images for offline use.
Picasso.with(this)
.load(downloadPath+imgDetailPhoto)
.placeholder(R.drawable.no_image)
.error(android.R.drawable.stat_notify_error)
.networkPolicy(NetworkPolicy.OFFLINE)//use this for offline support
.into(eventImage);
Above code is not worke while removing cache.so Picasso can't find image from cache.If not get image from cache we handle to get image online and display it. We achieve that using below code:
Picasso.with(getActivity())
.load(downloadPath+imgDetailPhoto)
.placeholder(R.drawable.no_image)
.error(android.R.drawable.stat_notify_error)
.networkPolicy(NetworkPolicy.OFFLINE)//user this for offline support
.into(eventImage, new Callback() {
#Override
public void onSuccess() {
}
#Override
public void onError() {
Picasso.with(getActivity())
.load(downloadPath+imgDetailPhoto)
.placeholder(R.drawable.no_image)
.error(android.R.drawable.stat_notify_error)
.networkPolicy(NetworkPolicy.OFFLINE)//user this for offline support
.into(eventImage, new Callback() {
#Override
public void onSuccess() {
}
#Override
public void onError() {
//get error if image not loaded
}
});
}
});
Picasso caches images for offline use.
I'm using it in a simple movie app where I display a bunch of movie posters. I can turn on airplane mode and my images are still there. Likewise, if I force close the application while in airplane mode, then open the app again, my images will still load.
Hope this helps.
P.S. check out Glide https://github.com/bumptech/glide. It's faster and has smoother loading than Picasso
From the UX point of view, it will be great to show the user a thumbnail first until the real image completes loading, then showing it to him, but Picasso uses only a resource file as the place holder like:
Picasso.with(context)
.load(url)
.placeholder(R.drawable.user_placeholder)
.into(imageView);
So, how can I use a thumbnail URL as the placeholder? , and if I should use Picasso twice, then how?
An issue is already opened on Picasso's github page with this request, but seems it won't be added to Picasso as per JakeWharton. So how could we do it with what's available in hand?
Thanks to raveN here & the comments on the original request on github, finally I've got a working solution:
Picasso.with(context)
.load(thumb) // thumbnail url goes here
.into(imageView, new Callback() {
#Override
public void onSuccess() {
Picasso.with(context)
.load(url) // image url goes here
.placeholder(imageView.getDrawable())
.into(imageView);
}
#Override
public void onError() {
}
});
The trick here is to get the drawable from the imageView (which is the thumbnail) after the first call & pass it as a placeholder to the second call
-- update --
I've made a blog post describing the whole scenario
You could write a simple helper which calls Picasso twice (as you mentioned).
I've not tested it, but it should go like
Picasso.with(context)
.load(thumbnailUrl)
.error(errorPlaceholderId)
.into(imageView, new Callback() {
#Override
public void onSuccess() {
// TODO Call Picasso once again here
}
#Override
public void onError() {
}
);
There are a couple of different ways to get your Picasso called twice. One method I could think of (again, not tested) is
public static void loadImageWithCallback(String url, Callback callback) {
Picasso.with(context)
.load(url)
.error(errorPlaceholderId)
.into(imageView, callback);
}
public static void loadImage(String url) {
Picasso.with(context)
.load(url)
.error(errorPlaceholderId)
.into(imageView);
}
loadImageWithCallback("http://example.com/mythumbnail.jpg", new Callback() {
#Override
public void onSuccess() {
loadImage("http://example.com/myRealImage.jpg");
}
#Override
public void onError() {
}
}
Edit: All I know is that Picasso provides this callback mechanism. I'm using it in my app to hide a ProgressBar that is displayed until the image is loaded. I'll hide it in success or error callbacks - so you'll have the option to get notified when image loading is done. Then you can simply call it again. I hope the above approach works.
I originally used AbdelHady's solution but found that the larger image is only loaded after the thumbnail is done loading so I came up with this instead.
Assuming you have a utility class in your project;
public final class U {
public static void picassoCombo(final RequestCreator thumbnail,
final RequestCreator large,
final ImageView imageView) {
Target target = new Target() {
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
imageView.setImageBitmap(bitmap);
}
#Override
public void onBitmapFailed(Drawable errorDrawable) {
imageView.setImageDrawable(errorDrawable);
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
thumbnail.into(imageView);
}
};
imageView.setTag(target); // To prevent target from being garbage collected
large.into(target);
}
}
Usage:
U.picassoCombo(
Picasso.with(context)
.load("http://lorempixel.com/200/100/sports/1/")
.placeholder(R.drawable.ic_image_placeholder),
Picasso.with(context)
.load("http://lorempixel.com/800/400/sports/1/")
.error(R.drawable.ic_image_broken),
imageView
);
In the above example the placeholder is set first, the thumbnail url is set next, and regardless of whether the thumbnail request is done, successful, or failed, the large image request is set once it is done. If the large image request failed, then the error drawable is set.
The only issue is that if you use setIndicatorsEnabled(true) the debug indicators don't show for the large request. As far as I can tell this seems to be by design according to this issue convo