I am currently downloading 471 thumbnails from a server,doubling the dimensions,saving it on the device and using the TableLayoutManager with custom image fields to display them. However, I think that creating these extra 471 custom image fields is causing a huge memory leak.
I monitored the memory usage while it was downloading and it only increased slowly to about 10-18 mb before the garbage collector kicked in,so it is fine.However, once all the thumbnails are cached on the phone,it uses about 100+ megabytes to read the images from the disk,double them in size,create the 471 custom image fields and display them. The total size of the 471 thumbnails is 427 kb. How could the system use that much memory to load those files?
However, If I where able to use a listfield like a tablelayoutmanager then it would I wouldn’t have to create those extra 471 custom image fields and just directly add the images to the listfield.
Has anyone had to do something similar or have an example on how to achieve a table like format using a listfield?
The 427kb is the download size of the PNG images. PNGs are compressed. When you open them up in memory they actually expand, so that each pixel in the image, could contain up to 4 bytes (ARGB) values (depending on the format) and also other PNG metadata.
Saving the thumbnails with double the size (dimensions), will not necessarily yield a file size with double size. It could be larger or smaller, depending on the image and how good the image compressor is.
Adding images directly to the list field won’t make any difference. You still will have them loaded in memory. What you need to do is have some sort of manageable in memory cache of say 20 images maximum. Your code needs to be clever enough to detect where in the list field the user is at any moment, and display images for that view.
So, let’s say each list field object (or row) has a tag associated with the respective image (e.g. filename). Once the user has finished scrolling up/down, you can then load the images for that view. If the first row displayed in the list field is row 20 and you can display 8 items, you will need to grab images 20 – 28 and load them in to the in-memory cache if they are not already there (so check the cache first). Then call invalidate() on the list field to ensure it repaints.
Threading:
a) You won’t need a thread to detect where the user is at any point. You should be able to use the moveFocus methods or navigation methods and figure out where the user is.
b) For loading images you need a queuing mechanism. Task queues are quite simple to implement, once you get your head around the threading/locking mechanism. Each task in the queue will load the image in it’s own thread.You will want to set a limit of how many tasks (threads) are active in the queue at once. I would go for 3-5 maximum (this is from experience on BB platforms). For queue implementations I would suggest by reading up about task/job queues, and producer/consumer problems.
The above mechanism is used a lot. This is why when you scroll down a contacts list for example, you might see a slight delay before the image of the contact is loaded and rendered next to the contact name.