I am building the application that will load list of news from the website. Each news/headline has an image. I want to save/cash the images so user does not has to download them again.
Q: In your opinion, what would be a better/more sufficient way: Loading images and saving them on the device or use the CacheManager? At the moment I am using the first solution and everything works fine. However, the website has many categories and even more news per category therefore there are lot of images saved on the device. Is it normal in this type of applications to save the images on the device?
Thanks for your help,
marqs
I don't think you should save the images on the device, because of many reasons:
Why wasting the device space on news images? All the user wants is to read the news and thats it. (In your case maybe open it later, but still - not forever)
You can save it on the device and make the app. delete those files after lets say 24 hours..
The main issue is the privacy issue, when the user is deleting the cache files he thinks all the webs he visited has wiped from the device, but in this case they aren't..
Maybe you can just add a "Clean Cache" button in the app. but after all I wrote I think using the Cache-manager is the best way - just because it was meant for those things exactly..
:)
Rotem
I didn't find a reason to use CacheManager. I used getCacheDir and stored everything on file. I have two levels of cache. First when I fetch it, I store in memory and disk. When in memory gets bigger than 30 objects, I started clearing the memory to make some room for the new images coming. However, I still keep the images around on disk and bring in to memory as needed. I found this to give me the smoothest scrolling. After about an hour, I start expiring the image on disk too.
Related
I'm developing an android app using Firebase back-end. Everything works fine, I have no problem whatsoever. The only problem is that, the data loading speed. Because it's a cloud-based system, sometimes it takes 4-5 (or even longer) seconds to load a user profile picture or simply to pull username from the database to display user. Now, you might say, well we don't even know how your data structure is stored in the no-SQL table but really I can't go wrong with that. I just structured it in a way that it's just a simple one read query. Or is it normal? Maybe Firebase loads data with some delay.
How you as other developers, get over this loading time? For example, I have a user picture, where the pic should be loaded from the Firebase database, but till pic is loaded, the image-view is just staying as a black view.
All of this depends on several factors that you can check.
Internet speed
Programming type
The size of the files (you probably need a lot of time to load for a
high volume file)
And another solution is to store the information you've previously received into the phone's memory(cache).
Is there a general guideline or rule of thumb on when I should cache a photo?
For example I have a grid view of smaller icon images. This page isn't at the beginning of the app so there's no guarantee a user sees it, these images could change server-side but for the most part they won't. Should I cache them because there are so many or not worry about them because they are small?
Another example would be if I click on one of the images mentioned above it will lead me to a view with one larger image, should I cache this image since it's larger or should I let the user make a network request each time?
I'm not looking for an answer for these specific questions, but rather a guideline to follow.
To clarify by caching I mean saving the file to storage. Also, is there a better method than this?
Thanks for the help!
Caching is an important feature in user experience, so even if there's no guarantee the user sees that particular 'page', it a nice thing to have.
Saving images in a cache depends directly on many variables:
- How much time does it take to regenerate images if not cached
- How many images are we talking about
- How often do they change
- What size is each image
For example, having 100 thumbnails of images that change every month makes a lot of sense. Caching 200 images with 1024x768 resolution that change very often doesn't.... or does it? The answer is very variable.
Also cache should always have storage boundaries. Even in the previous example with the large images, you could limit the cache to a a certain storage capacity.
Normally the cache saves a local copy of the most recently used items. But you can implement a more sophisticated algorithm, for example, saving the most visited images instead of caching the most recently used.
I am making an attempt to build the most efficient way of caching images downloaded from the web for my app, a few years ago I tried to do this and could not find an efficient method of making this work until I stumbled upon the lazylist adapter found here:
Lazy load of images in ListView
this worked well until android 4.0 was introduced, at this point the app would crash after loading 10 to 20 images, as opposed to before where I could simply load up as many as I wanted without any issues, this I later found out was a result of the Ice cream sandwich having a set limit on memory usage per app, which didnt exist in Gingerbread 2.3 and below, I eventually decided to just clear the cache every 10 or so images to avoid crashing, however the user experience wasn't very good as a result of doing this and the app used tons of data as it was constantly redownloading images over and over again that were already viewed, I have since attempted to use an lru cache but this does not seem to work at all, especially when I leave the app and relaunch it the images are all released it seems, I need a better way of doing this and I have noticed that other apps such as instagram seem to have found a way to cache hundreds of megabytes of images, Im consistently having to manually clear the instagram cache in my settings because it seems that they are to able to store an infinite sized cache that seeming never ejects its contents, does anyone know how to build this kind of cache?
You can try using https://github.com/nostra13/Android-Universal-Image-Loader
library. This does most of the hardwork for you.
the way I wold suggest would be to store the images from the web to the sdcard or something then store the URI where the mage is located. The in your list just load the image from the uri.
If your images are big in size you should probably rezise the image before you save it so that you use less memory and it will load faster since the processing has already been done
BTW the memory limit always existed in android
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 a listview and each listview item when clicked opens a gallery (conating 30 + images ) to be downloaded (using the urls).I don't want to re - download the images on next visit and also want the images to be present when i click on list in offline mode.
I went through several links in SO and am a bit confused on which approach to follow:
1> Use bytearray and store the images in sqlite db.
2> use context -> getExternalCacheDir() to store it on the
external memory (this wont work on devices with no external
memory.)
3> Use SoftReferences as suggested in following link
http://android-developers.blogspot.in/2010/07/multithreading-for-performance.html
Please help to guide me on the best approach to handle around 1000 + images which works in offline mode as well.
1000 images.....I sure hope they're thumbnails or you're going to end using a lot of storage space.
You should really only cache what you need and what images are used repeatedly. Both options 1 and 2 are dependant on the phone even having storage space, if there's no space then you won't be caching much to disk. 3 won't store images permanently, if the app is put in the background and gets killed and so will the cache.
It's hard to say what the correct decision here is without knowing the inner workings and requirements of the app.
Just going by what you want then I would say go with several solutions
If there's external storage write to that, if not use internal storage, if there's not enough space internally use the soft references.
I have always found that out of the box caching solutions never fit quite right with my apps and wind up writing my own cache. Sorry I can't give a better answer.
PS. If you're not careful with 3 you might download too much and run into an OutOfMemoryException.
PPS. 3 can also throw a RejectedExecutionException which is caused by too many async tasks being started at once (eg scrolling quickly through a listview that gets an image via asynctask)