Currently, I'm downloading a list of ParseObjects that have a URL, which I then use to load gifs over the network into my list items. This is obviously quite slow for a list, and even using Glide and only displaying the first frame, it still takes several seconds to display anything into the view.
What I'd like to do, is write some custom Cloud Code to only send the client the first frame of the gif and use that as a preview to display in the list, then download the actual gif when the preview is clicked on. Obviously I would have to have the gifs uploaded as a ParseFile instead of just a URL but that isnt the issue.
Could this be done? If so, how?
Related
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
I'm currently building an app for learning purpose (new to android programming) that lets the users to upload
image to the server and watch other users images (by swipe the screen for example).
I finally succeeded to let the user upload image to the server and I was wondering how to code the part that retrieve the images from the server and present them in the app.
Assuming I have at the time million images, I don't want the app to load all the images in the same time because it will take a lot of time.
And all the guides I'v seen makes the app to load all the images at once.
So my question is what is the recommended way to do so?
Hope I was clear.
Thanks.
Let's say you have an array with a million images in your server to load in your app that will be shown in a RecyclerViewand assuming a screen can fit about 5 images.
In this case scenario a good approach would be to fetch 10 images at a time and load them in a RecyclerView. Load the first 10 images and once the user reaches the end of the scroll load some more images, add them to the previous retrieved image list, and finally update your RecyclerView to present them. With some effort you may be able to create a Facebook look alike effect.
RecyclerView has methods that will easily help you detect the end of scroll (there are plenty of ways you can find in StackOverFlow). Every time you detect an end of scroll, just upload more images.
This is one example: How to know whether a RecyclerView / LinearLayoutManager is scrolled to top or bottom?
Use FlexBox Layout for better UI Design to show images
https://github.com/google/flexbox-layout
See how this cat images are shown using FlexBox Layout
After calling an API, I get a response of some hundreds of images in the BASE64 format in JSON and I will display them in recyclerview using Glide. Is it an efficient way to get all images in one response and show all images in recyclerview in one shot or do I ask backend developer to send fixed number of images in one response say 10-15 and again make a request when all images are loaded in recyclerview using pagination. Please suggest some best way.
why you store image in BASE64 format on server. change api response and use image url instead of Base64 string. Use picasso for display image in recycleview with resize image.
Add pagination in server api for improve app performance.
It is better to use pagination in RecyclerView so that the user doesn't have to wait for a long time.
You should use pagination to load the data faster and save data. Apart from that if you are using Glide then you dont need the Base64 of image, The url of the image will be enought to diplay the images in the recyclerview.
That will use a lot of memory. Besides, loading hundreds of image will takes longer time, more data and also reduce performance.
Instead of doing that, you can load data from the data source using a load more. If the user wants to load more data then load more data using pagination.
I am trying to get the same nice UI effect guys at Whatsapp did. Each time I receive some image, not matter of its size, I can see blurred thumbnail in a matter of 1 sec, and over it an indicator that the real image is being downloaded.
How do they do this? I want to achieve the same effect when users download images from our server. I am not sure if they are doing some server-side image processing, or there is a built-in feature in Android SDK which can do this.
Let's say a user requests an image of 4MB. Almost instantly he clicks download, a blurred thumbnail of the image will appear over the screen and download status indicator over it. I am mainly interested how to get image preview so quickly, literally in a matter of 1 sec (feels like being instantly).
PS. Similar effect has StackOverflow when you try to upload an image. When you drag it to the upload popup, you see its preview almost instantly. I guess Stackoverflow does this by using client side scripting, which we cannot apply in Android app. But this is a good showcase of what I need (in case you don't use Whatsapp).
Basically what is happening in these situations is you need to request a blurred thumbnail from the server (Usually very small so it downloads quickly), and then begin the download of the full image. This is something that has to be done by the server.
Update:
You can now use a technology like progressive jpeg to achieve the same effect without having your server store two separate images. Progressive jpegs basically encode a very low quality image in the first bytes of an image, and then as the image continues to load the quality improves. This may not be the exact effect you are looking for, but it should be able to show a quick low quality preview while loading in the full sized image. Currently the only way to load these on Android is with Facebook's Fresco library.
I have another theory. I think the method used here is that before publishing the message, they have some algorithm to generate a lightweight fuzzy low-quality picture (in the sender) and then send the contents of that array (a few bytes as a byte[] array maybe) along the published message .. now once the receiver receives the message, he can instantly display that fuzzy image and get the full image by doing a full request to the server .. What makes me think this is that if they are going to request the thumbnail from the server then why not have a detailed thumbnail ? it can be small in size as well .. why have a fuzzy thumbnail that is only a mere shallow representation of the original one and not complete like thumbnails we see in the web.
I believe that there are two part in this process
First is message part which is loaded from api server which will have text contents of the message and very small/blurred image (Base64 encoded string of the image) with url to actual video. example
{message:"Hi this is my video uploaded..", thumbnail:"..base64 string of image", url:"...url to video file with key or without"}
Second is Media part which starts when user click on download button after seeing the preview image from url served with message.
While uploading the message we can also so the same thing either we
generate thumbnail/blurred image and submit the message in two part
First upload message with thumbnail to api server and get key for media server
Submit video to media server with key provided by api server.
Or
First upload message to api server and get key for media server
Submit video to media server with key provided by api server and let
server generate thumbnail for video.
Here i believe that we are running two separate server one for handling static contents and another for api calls.
Hope you all agree with me or suggest any correction.
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.