I'm trying to create a CRUD android application.
Now, when the List Activity is shown, it will display the items created along with a thumbnail of the original image.
What is the best practice for displaying a thumbnail in an Android application with Volley? Should I generate a thumbnail for the images uploaded or just re-size the image at the client side?
It's hard to come up with a general answer for this questions because it all depends on how many images you're trying to download and how important showing the thumbnails is.
I would personally generate the thumbnails on the server side as soon as they are uploaded by the user. Doing this has several advantages:
All your app has to do is request the thumbnail and render it, which is much simpler and less CPU-intensive than using Volley's ImageRequest.
Smaller images means less data usage. You definitely don't want your app to download a 10MB 25-megapixel image over a 3G connection just to shrink it to a 100x100 thumbnail that the user might not even care about.
The only drawback that I can think of is that you might have to generate multiple thumbnails, one for each screen size (e.g. one for hdpi screens and another for xxhdpi). This is slightly more expensive on the server side but might make your UI look much better.
Also, remember to cache thumbnails in your app's cache directory so you don't have to re-request them every single time you want to show them.
Related
I have an app. it has a recyclerView on main screen .
in recyclerView Item layout I have ImageView. the ImageView size is must be responsive. I want to set the images sizes based on screen size. when I received the json images link from server , I do not have any local resources. so I could not put them in mdpi-hdpi-xhdpi-... folders. I want to know what is the standard way for loading images that is received in json format from server . I read a article in this link:
What size to store image on server to use with Android app
my friends says you should fetch all images sizes from servers in json format and make decision what you want to load.
in this link He said send the density to server and it makes decision what is best size for your device.
which one is the most common way ?
If I load all images sizes from server , Should I check density of the device to load which one ?
Not a full answer but in general the device should only have to do one request for getting images, using a library like Glide.
You could use device density to determine the size that you want to ask for, but you and the server should both know beforehand where you can find the url or rather what suffix you have to use to find the lower/higher quality image.
Libraries like Glide handle a lot for you so I would recommend trying all of the features that it provides (like caching) and then afterwards checking if imagesize is really something that you need to optimize.
Especially at the start I wouldn't worry too much about it in small apps because there isn't going to be a noticable difference for users/server load anyways.
in my recent android project I have to get a large number of images from the web and show them in my main activity (something like explore part of the Instagram app). I used a recyclerView with gridLayoutManager of 3 columns and I have to get something like 700 images from URL. When I open the app and comment the getting image part, app work perfectly fine (the app get the information of each tile but doesn't display the images). But when I start setting image bitmaps the app start becoming laggy and crash after about a hundred images loaded.
What do you recommend me to do ?
And another question: Was using recyclerView a smart idea ?
Thanks for your reply.
Don't load hundreds of images. That requires a few things:
1)Don't store images in memory in the adapter. Store the url/resourceid/whatever of the image so you can load it on demand.
2)Use an LRU cache of images, limited in size and load your images through that.
3)Make sure that however you download images does not spawn too many concurrent requests, and that requests are canceled when no longer needed (when the view it would go into is recycled).
4)I'd suggest downloading the images and writing them to disk, then loading them from disk as needed. This will prevent you from having to keep the entire file in memory to decode it while downloading it, which will reduce your memory usage while downloading.
5)Do not decode the image on the UI thread. Do it on another thread.
6)If you don't need to display images fullsize, make thumbnails.
Images in a RecyclerView, especially if being downloaded need a lot of work to do well and handle rapid scrolling.
You should post some code here but seems you are asking for some efficient setup.
First of all, try using some image caching libraries like Glide or
Picasso. It manages and caches your images locally so you don't end up
making multiple requests for the same image.
This solves most of your problem and don't try to load 700 images
altogether and display use lazy loading means load first 10-20 images
first and when user scrolls make another API call for another 10-20
and so on.
Here is an article on how to use Glide and how it works.
https://futurestud.io/tutorials/glide-image-resizing-scaling
Lets consider the following, I have an app with several dozen photos I want to show the user at any given time.
Right now I'm creating multiple files for each image, sizing them for different screen sizes and storing them in their respective drawable folders.
It's increasing the size of my app dramatically.
So here is my question: Is it possible to store the images on a server and use an image library like Picasso, Fresco or something else (open to anything) to fetch that image and scale it down for the device it's running on without risking running out of memory?
I'm worried that fetching a large image, loading it into memory and then resizing it will cause the same problem as trying to display it on older devices with little memory available to them.
You can write methods to request different images sizes from your server based on client info. Just write a method to measure the screen size and then request the appropriate image based on a URL endpoint (like http://myimageserver.com/images/ldpi/image1.png).
You can do optimization post-download, such as scaling, before saving the image to a local file store.
Using a reputable image loading library is a valid method (my own favourite is Glide).
The answer to your question really depends on the number of images you want to show! If there are lots, then yes storing them on a server is probably best, but also the most time-consuming and expensive (both in time and money).
Your other (easier) option is to keep the originals in the assets folder, and use your image loader to scale and load them for you. The correct path for an image in your assets folder is file:///android_asset/your_image_here.jpg. This way, you're only keeping one version of each photo in your apk and they'll load much faster.
In my application I have to show many images (say >1000).
All these images comes from network. For now, I am downloading all images and passing them to an adapter which was set to GridView.
My problem is downloading all images at once occupies a lot of runtime memory. So I want to change my design.
Is there any way to handle images/bitmaps in large number effectively? Like downloading 100 images, then again another 100 erasing previous 100 (as per need).
You can try these optimisations:
Decrease number of images, do you really need 100 in one go?
Download image thumbnails, do you really need full-sized non-compressed images?
Cache next images, pre-load some images before user asks for them
Profile your app, see where time is consumed
Use several threads, at least one for pulling data and one for UI
I think you need to take a look at UIL
Which is helpful to you.
My Problem deals with Memory, I have a Web service that provide me a List of Urls. Each URL corresponds to a large image. My Mobile app have to parse the xml provided by the web service and than show in a GridView these images. I tried several features in order to display images such as:
Multithreading
Lazy Loading
Reduce image size using inSampleSize ( this causes my app takes too long)
should i have to attach for each large image a thumbnail image, and make the web service return to me the list of all thumbnails, after that show these thumbnail to the user, and if he clicks on one of them than i have to show the large image in a separate view, i have this idea because i noticed when i show one image i don't get an outofMemory exception!!
Is this a reliable solution? is there a better way?
Welcome to one of the hardest issues on Android. First I would start by reading this new documentation google wrote on how to handle bitmaps. Its not a light read, but you probably need to read it all the way through. It has only been up for a few weeks so you may not have seen it. It details many of the things you mentioned such as multithreading, lazy loading, and down sampling. They also recommend using an image cache.
Downloading the large images for each image and then down sampling is going to be very inefficient. First the download size is larger than needed. Second you need to load it into memory to perform the down sample and third down sampling is somewhat slow.
I would have the web api return you a list of thumbnail urls and full image urls that you can lazy download as the view comes on screen and use the cache to keep them around a while. Make sure you down sample the sizes of the thumbnails as well. I would then when the user clicks on an image go download the full image and on the background when it arrives down sample it before displaying it.