I want to download all images from server and store it in a cache.In most of cases, downloaded images are directly bound to the imageView(e.g. Picasso). I want to use same functionalities in android which is provided by SDWebImage("https://github.com/rs/SDWebImage").
Shutterbug is a good library for this purpose (https://github.com/applidium/Shutterbug). I've used this myself in a few apps and it works well. You can either use the Shutterbug FetchableImageView (which extends ImageView and you give it a URL rather than a bitmap or resource ID and it will display the image when download is complete) or you can use the ShutterbugManager which allows you to control what happens after downloading and caching. All the caching is done for you, it's pretty awesome :)
There are good instructions on the GitHub page's README on how to use both, and there is a demo project too.
EDIT: Just noticed your comment. If you don't want to bind to an ImageView, you can use the ShutterbugManager to download the image and then do whatever with it. Any subsequent calls to the download method will fetch the image from the cache rather than doing an HTTP call again.
public void downloadImage(Context context, String url) {
ShutterbugManager.getSharedImageManager(context).download(url, new ShutterbugManager.ShutterbugManagerListener() {
#Override
public void onImageSuccess(ShutterbugManager manager, Bitmap bitmap, String arg2) {
// Do what you like with the Bitmap here.
}
#Override
public void onImageFailure(ShutterbugManager arg0, String arg1) {
// Failure :(
}
});
}
Related
I'm using Fresco library to display images in my Android app. I'd like to display some images (jpg or png) that I have set with public grants.
When I was doing quick tests, I just took any image from internet to set a URL, but when using the real ones that I need to use, I have the following url https://drive.google.com/uc?export=view&id=<>, but as it is a redirect and, once redirected, new url is not the image itself, Fresco is unable to display it.
I have tried Picasso as an alternative library, but with out any success.
I have also tried the download url for both libraries (https://drive.google.com/uc?export=download&id=<>). But no result.
Anybody knows how could it be possible to get this images? Or the only solution is to download it (using the second url) processing the object received store a bitmap of it and displaying it?
For downloading it, what should i use and how? retrofit?
Thanks in advance.
Fresco supports different network stacks. For example, you can use OkHttp with Fresco, which should follow redirects or modify the default one to allow redirects - or write your own based on them.
Guide for OkHttp: http://frescolib.org/docs/using-other-network-layers.html
Related GitHub issue: https://github.com/facebook/fresco/issues/61
I found a solution for this problem (but could be only applicable if you use Google Cloud or Google Script).
It consists on creating a doGet() service with the following code inside:
var file = DriveApp.getFileById(fileId)
return Utilities.base64Encode(file.getBlob().getBytes());
and use that base64 value in your app. With this format, Fresco can do the magic
It is not an immediate solution, and requires to do somework in other platform that is not your Android app, but it works perfectly.
Are you sure that there is no problems with your URLs?
Picasso works with direct URLs like: https://kudago.com/media/images/place/06/66/06662fda6309ce1ee9116d13bd1c66d5.jpg
Then you can download your image like:
Picasso.with(this)
.load(url)
.noFade()
.placeholder(R.drawable.placeholder_grey) //if you want to use a stub
.into(imageView, new com.squareup.picasso.Callback() {
#Override
public void onSuccess() {
//here you can operate with image after it is downloaded
}
#Override
public void onError() {
}
});
Hope it will help you.
I've been reading quite a lot on the topic, still not quite clear though. At the moment I'm creating an app, loading an image and a text on one screen. For loading the images I opted for Glide, but where is the most appropriate place to read them from? All of the tutorials I passed pass the image's URL. Isn't it slower when loaded from the net? Thanks a lot!
If you care for apk size then do not put these images static. Instead you can keep these images on server(your or free server) and easily load those images using libraries like Glide or Picasso.
Isn't it slower when loaded from the net?
No. It will download image once and then cache it for future use. So it's very fast.
If you think apk size will doesn't matter for you and user should not face problem due to unavailability of internet then you can keep those images static inside app iteself.
If you want to build an app that uses dynamic images or you want to update your images without updating your application, getting them from the server is better. And in my opition picasso is easy to use and straightforward. Also uses it's own framework caching. But if you think that your images wont change, put them in an asset folder so that they are in app's internal memory. Getting them from the server has it's downsides like you need to use a placeholder images because they won't be retrieved immediately.
You must use caching mechanisms if you want the images always from network. The system I follow is like this: (PS. I use Picasso, fast and reliable):
Picasso.with(this).load(URL).networkPolicy(NetworkPolicy.OFFLINE). //load from cache first time
into(imageView, new Callback() { //Picasso Callback
#Override
public void onSuccess() {
if(isNetworkAvailable()) { // if network available then update the cache for this URL
Picasso.with(MyActivity.this).invalidate(URL);
}
progress.setVisibility(View.GONE); // Progressbar
}
#Override
public void onError() { // Image not loaded, try again one last time
Picasso.with(MyActivity.this).load(URL).into(imageView, new Callback() {
#Override
public void onSuccess() {
progress.setVisibility(View.GONE);
}
#Override
public void onError() {
progress.setVisibility(View.GONE);
}
});
}
});
i am downloading (pref-etch) images from server at some time of interval
so i wanted to know what is the best way to download images
asyntask
service
intentservice
please help
Case 1: If you have to download very few images (like one or two in an activity) from Internet, then use Asynctask .
Case 2: If you have to download many images specially for ListView items , you must have to implement it in a dedicated background thread by using HandlerThread, Handler , message and Looper in Android. Avoid using a service here. Also, you have to implement image caching as you dont want to download the same image multiple times in a session.
Advice: If the second is your case, don't implement the above by yourself. Save your time and use some awesome, efficient and fast libraries used by millions of Android apps.
You can use:
Picasso by Square
Glide
Volley
Edit: How to use Picasso for downloading images.
All the above mentioned libraries can do that beautifully. I am sharing the solution with Picasso.
Picasso.with(mContext).load("url").into(new Target() {
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom loadedFrom) {
//save the bitmap into permanent storage or do whatever you want like showing in some ImageView etc.
}
#Override
public void onBitmapFailed(Drawable drawable) {
}
#Override
public void onPrepareLoad(Drawable drawable) {
}
});
Hope this helps. If still have any issue , please feel free to comment.
I am using Picasso to handle image loading and caching in my Android Udacity project and I am noticing the caching is not working as I'd expect:
As you can see on the left fragment, the image has already loaded in an earlier thread. Now, with the same URL link, I am asking Picasso to place that image in the fragment on the right.
Here is the code which generates the grid view on the left fragment (and occurs first):
https://github.com/esend7881/udacity-android-popmovie/blob/a9a1b9a19a37594bb5edd736b7ec59229fb5905a/app/src/main/java/com/ericsender/android_nanodegree/popmovie/adapters/GridViewAdapter.java#L71
String load = String.format(sImgUrl, sImgSize, movie.poster_path);
Picasso.with(mContext.getApplicationContext())
.load(load)
.placeholder(R.drawable.abc_btn_rating_star_on_mtrl_alpha)
.error(R.drawable.abc_btn_rating_star_off_mtrl_alpha)
.resize(550, 775)
.into(viewHolder.imageView);
And then here is the code which runs in the right fragment:
https://github.com/esend7881/udacity-android-popmovie/blob/a9a1b9a19a37594bb5edd736b7ec59229fb5905a/app/src/main/java/com/ericsender/android_nanodegree/popmovie/fragments/MovieDetailsFragment.java#L308
Picasso.with(getActivity().getApplicationContext())
.load(String.format(sImgUrl, sImgSize, mMovieObj.poster_path))
.error(R.drawable.blank)
.fit()// .resize(366, 516)
.into(mMovieThumb, new com.squareup.picasso.Callback() {
#Override
public void onSuccess() {
Utils.log(sw.toString());
Utils.hideViewSafe(mMovieThumbProgress);
}
#Override
public void onError() {
Utils.log(sw.toString());
Utils.hideViewSafe(mMovieThumbProgress);
}
});
I am using the same application context in each as well as the load text:
String.format(sImgUrl, sImgSize, mMovieObj.poster_path))
and
getActivity().getApplicationContext()
So, I would think Picasso ought to detect when the exact same URL load link appears in the same context within a short period of time from each other and Picasso would then load the exact same image back into the app.
If this is not how Picasso caching works, then how does it?
As a comment mentioned, I'd guess this is affected by the size of the image being different in both fragments.
I'd recommend using https://github.com/facebook/fresco instead of picasso. It's more efficient, especially with different sizes. You can also directly access cached files if required https://github.com/facebook/fresco/issues/80
It's probably related to the HTTP headers received when getting the image that do not allow caching, as Picasso relies on an HTTP component to do the caching.
Try uploading your image on imgur, try hardcoding that path and see if it works. If that's the case, you'll have to find a workaround on how to get the image from the movie database.
Care: No code here, only text and some questions about bitmap caching
I'm currently developing an App which is almost finished. The only thing left, that I would like to do is caching images. Because, at the moment, when the user opens the app the app downloads images from a server. Those images are not static, that means they can change every minute/hour/day. I don't know when they change, because it's a list of images gathered by the amount of twitter shares, facebook likes etc. That means, when a picture has 100 likes and 100 tweets it is place 1. But when another picture gets more likes and tweets it gets rank 1 and the other one will be placed as rank 2. This isn't exactly my app, but just so you understand the principle.
Now I looked into Bitmap caching so the user doesn't have to download the same images over and over. The question I do have is how do I do it? I mean, i Understand HOW to cache bitmaps.
I looked into this documentation article: http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html
But, the problem is, how do I know if the Bitmap already got downloaded and has been cached or if I have to download it again? Don't I have to download the image first to check if I have this particular image already in my system?
I thought about getting the URL of the image, then convert it into a hash. And then, save the files to the cache with the hash as filename. Then, when the image URL comes it will be checked wether the image is available in the cache or not. If it is it will be loaded if not it will be downloaded. Would that the way to go be?
Or am I misunderstanding bitmap caching and it does it from its own already?
my best advice on those cases is: Do not try to re-invent the wheel.
Image loading/caching is a very complex task in Android and a lot of good developers already did that. Just re-use their work.
My personal preference is Picasso http://square.github.io/picasso/
to load stuff with it is one very simple line of code:
Picasso.with(context).load(url).into(imgView);
it's that simple!
It does both RAM and disk cache, handles all threading issues and use the excellent network layer okHttp.
edit:
and to get access directly to the Bitmap you can:
Picasso.with(context).load(url).into(new Target() {
void onBitmapLoaded(Bitmap bitmap, LoadedFrom from){
// this will be called on the UI thread after load finishes
}
void onBitmapFailed(Drawable errorDrawable){
}
void onPrepareLoad(Drawable placeHolderDrawable){
}
});
Check this library:
http://code.google.com/p/android-query/wiki/ImageLoading
It does caching automagically
example
//fetch a remote resource in raw bitmap
String url = "http://www.vikispot.com/z/images/vikispot/android-w.png";
aq.ajax(url, Bitmap.class, new AjaxCallback<Bitmap>() {
#Override
public void callback(String url, Bitmap object, AjaxStatus status) {
}
});.
http://code.google.com/p/android-query/wiki/AsyncAPI
You can try https://github.com/thest1/LazyList
the project code was designed for listviews, but still, its purpose is to download images from URLs in the backgroud so the user doesn't have to hold on the whole downloading time.
you take these JAVA classes : FileCache, ImageLoader, MemoryCache, import them into your project,
for downloading an image you just call imageLoader.DisplayImage(URL,ImageView);
the best part is that it takes care of the cache itself so you don't have to worry about that
hope this helps