I am developing Android app now where I need to store image Url in DB for each object and then load this image from the web (if connection is on) OR get it form cache (if not).
Picasso seems to be best lib for handling images in Android, so I starter using it. But I can not get how do I use it properly for my case. Even more - Images strangely are loaded into views right after they are first time get from API but if user starts app again, we can see placeholder only (even with internet connection on). Can someone suggest a solution or at least any kind of idea of best way to do this?
My code in Adapter (is is also same in ShowActivity):
String img_url = item.getImage(); // img_url is valid image url
Picasso.with(mContext).load(img_url).placeholder(R.drawable.plchldr).fit().centerCrop().into(holder.image);
I tried to use Picasso at the start as well, and found out that their caching system is horrible.
It would cache some images i downloaded, but not others, and would therefore leave alot of images with placeholders.
I suggest you try Universal-Image-Loader (https://github.com/nostra13/Android-Universal-Image-Loader). I'm currently using this to cache all images in my app, and it works flawlessly (Around 200 images atm).
Finally got the problem - API is returning valid image url BUT actually it (image) is hosted on S3 cloud and it is expiring till the user loads application again. So, actually saving expiring image URL is useless in this situation. I am not sure what will I do here (it seems that the only way here is hard one - storing images on SD as Bitmap). But I just wanted to tell this for those who will get similar issue.
Related
I am building an android application which requires displaying images as a flip-view which will be retrieved from server. I have considered two approaches
Retrieving images from server URL and then displaying OR
Storing the image in db at server(MySQL) and then retrieving it from sq-lite on android application
My question is, which approach will be better considering everything (performance, etc.)?
Any other better approach is also welcome :)
This depends upon your Application and products you are going to display using Images, If they are not updated frequently then it would be better to use caching for faster user experience but if data is regulatory updated and previous data is keep getting filtered then always load using network.
Another approach you can just store latest 10-20 entries in your Database and as soon as you opens the application he can see some data and new data gets downloaded, this approach keeps users engage don't leave them your app just because every time they see loading.
For Image caching purposes there various good libraries avaible which are stable solutions for multiple images downloading as well as caching purposes E.g.
UniversalImageLoader, picasso, Volley
A good approach could be store locally images locally on demand, and keep it on cache, if the image changes on future you can invalidate your cache and download a new image.
I have used in a project a library that helps me a lot with to download the image in background, allows you also load image from cache automatically if stored previously or invalidate the cache. The library is android-query and here is an example of how you could use it.
You store images locally and load then to your app from local storage (This happens in a background thread)
You update the local storage by fetching the images in background, when needed, and then trigger the load from local storage (This also happens in a background thread)
This way you won get ANR's (application not responding) because of slow or missing internet connection, and you will be able to show images without connection at all.
I am using felipecsl Android-ImageManager library to download some images from one of our servers and load it in a list view. In my Android application I have a feature to change that downloaded image from app side and upload it to server.
I do know how to load the image from URL because it is well documented with the above mentioned link. What I need is to change/delete a particular cached item and replace it with my new image from Android application side.
Let me explain it further. Normally what happens is, it loads an image from the provided URL and caches it in the manager's LRU and Disk cache. Then the second time call to that same URL, if the image is already cached, fetches it from the cache even I have set a different image from my application side.
Therefore how can I either delete that URL from cache OR set the new image for the cache of that same URL.
I have tried something like below, but seems it is not working.
imageManager.getCacheManager().getMemoryCache().put(ImageManager.getCacheKeyForJob(myUrl, jobOptions), bitmap);
That is not really supported by the library. If you need to do this kind of more advanced cache management, you can use Picasso (https://github.com/square/picasso), where you can set your own cache manager and have more control over your cached images.
Is it possible to cache a list of website urls, image urls etc without opening them first in a webview? I have a list of img urls coming from a feed that i want to cache on download. i have already posted a question about this but have gotten no response here is my previous question. (https://stackoverflow.com/questions/21831464/cache-image-urls-android)
It's not possible to drop things into the WebView's cache directly. The only way that would not require preloading in an "off-screen" WebView (which is totally possible, btw.) would be to download the images yourself and serve them back to the WebView using shouldInterceptRequest.
I would recommend caution with the shouldInterceptRequest-based approach though. It's easy to hurt performance when using shouldInterceptRequest (see here). Also, you need to take care of removing stale images from your 'cache'.
I'm making an android app, here the images are getting from Cloud, is it good idea to download images and save it & use it further. Or download images every-time user uses the app, what idea you prefer is the best?
Because downloading images always is slow & its bad i know but at some point if the images are updated then how to get to know about it?
You should definitely cache your downloaded files!
Do it in your internal app directory where only you do have access to (or otherwise external storage, thats still ok).
Bandwidth and connections are always expensive and should kept low as much as possible.
So your user can see images fast even on a bad connection and your app doesn't waste his valuable bandwidth of a users data plan.
Maybe this could also help you:
https://github.com/novoda/ImageLoader
http://www.androidhive.info/2012/07/android-loading-image-from-url-http/
Make it easy on yourself and use something like Android Smart Image View. It takes care of loading and caching, and it's just about a drop-in replacement for Android's ImageView. Universal Image Loader is another alternative, more configurable, but not as quick to implement.
I used https://github.com/nostra13/Android-Universal-Image-Loader
but I think you not want only download and cache.
these no trick ,if you want check weather the image update or not, you can add metadata for image, just like md5 .
in html and browser, you can set expires header for a image:
enter link description here
but in android app, you control all yourself.
Downloading images and saving them is probably the best way to do it because you don't want to download the same images over and over. If the images are updated you can delete the older one and download the new ones. Just make sure you don't download/save a million images. Take a look at this library. It has a built-in cache on sdcard/external sd.
Downloading images from the net for display, with possible requirement of caching is a very common problem that many people have solved, you can try these solutions to see which fits you:
Ion (https://github.com/koush/ion) - very flexible and feature complete, plus it can download more than images but JSON, Strings, Files, and Java types as well. The part that I really like about this is that it can automatically cancel operations when the calling Activity finishes, so users don't waste time & bandwidth downloading images that will no longer be displayed
Universal Image Loader (https://github.com/nostra13/Android-Universal-Image-Loader) - equally capable for most use cases but for downloading/caching images only
I have an Android application that would retrieve data (images+text) from a php remote server and display them in a GridView.
I am doing the operation in the background using Loaders. I have separate connections for images and texts since retrieving images would take longer and I want to display the texts immediately. The texts are encoded with Json on the server after being retrieved from MySQL. On the app, I am parsing the Json Objects and displaying the texts as I need.
The problem is with images. I am not sure if encoding the images with Json would be a good idea. Also the images are saved as blob in the database, in order to encode them with Json I need to use base64_encode() before which is not efficient. I have seen many posts about this, but it’s always a simple example when you have to get one image. In my case I’ll be retrieving up to 30 small-size images.
My question is, I can proceed with what I just presented, but it seems that there should be a better way to do this. What do you think about this? Am I going the wrong way?
Also I was thinking if I can display each image separately in the gridview once it is ready (not waiting for all the images to be ready) just like in the “Google Play App”’s GridView. What approach can I take to achieve this?
Thanks in advance folks!
Best approach in my eyes would be to download the image files as normal image files via a HTTP get request. Make sure it is threaded of course, and have a thread pool that you can queue up requests into, and have 2-3 threads go through and download.
In terms of saving them, I would personally move away from saving to blob in a database, and opt to save them to the persisted storage in your application's private directory. Saving the image files with their filename as their id in the database you have created will be much quicker for loading them back in.
You can also hold a reference to the ImageView, and have it display a place-holder initially, with a successful HTTP request replacing the bitmap of the ImageView with the one you have just downloaded/read in from storage.
You can also do some image caching within the HTTP request you make.
ImageView myImageView = findViewById(R.id.testImage);
URL url = new URL("http://www.website.com/image.jpg");
URLConnection connection = url.openConnection();
connection.setUseCaches(true);
Object response = connection.getContent();
if (response instanceof Bitmap) {
Bitmap bitmap = (Bitmap)response;
myImageView.setBitmap(bitmap);
}
It also may be helpful to lookup the uses of the LRUCache, which performs a lot of caching functionality for you.
Check out this link at the Android Developer site for a good in depth guide to image caching
Edit:
You can use the advice in Robert Rowntree's answer to load bitmaps more efficiently to cut down on your memory use as well. The link provided details loading of bitmaps using less memory, something that would work well if you are creating thumbnails from larger images downloaded over the web and saved off to local storage.
IMO - there are 2 issues , moving the images across the network to the client and getting them loaded.
Assuming that you are using http as the protocol, you should have a multithreaded solution for http as is available in apache httpclient package. That will get the pictures to the phone fast.
Then , you have to present the pics by getting them into memory and a cache. Here you can consider what 'gallery3D' app does with its grid and bitmaps but its pretty complicated to read thru that code.
check out - http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
check out code samples for loading thumbs from bitmaps.