GridView - hold more offscreen views? - android

I'm having an issue with an adapter for a grid view. The adapter causes a bitmap to be loaded every time a particular item is needed. I've got a disk cache and memory cache and I'm disabling loading while scrolling, so generally speaking, the gridview is quick.
But what I'd really like is to eliminate constantly having to rebind a particular Bitmap to an ImageView. Since the gridview is reusing views, the getView method has to keep reseting the ImageView and reloading the image from memory. This creates a really stupid effect as items slide offscreen and when returned to have a delay as the bitmap is read from the memory cache and posted to the ImageView.
Is there a way to get the GridView to 'hold on to' more views instead of being really frugal? I have a maximum of about 20 items and im scaling all the bitmaps, so I'd really like to just hold on to more of the views if possible.

I was able to solve this using a better in memory cache. The real distinction was to add a mechanism to check if the image was in memory and not 'reset' the view if the required image was in memory. It still seems bogus that there is not an easy way to set the number of cached views off screen for grid view, but better memory cache management made the problem less noticeable.

Related

Why does scrolling a scrollview increase memory usage a lot?

I have a acrollview which contains maybe 15 rows in imageview (own special listview). Each row contains text and cross bitmap.
When I first create the scrollview there is almost no memory usage, but at the moment I touch it to scroll, memory usage is increased by ~2 MB.
This tends to make GC run which makes scrolling very choppy.
I'm reusing the views, so this can not be it. Any ideas?
I set bitmap into imageview immediately, not from internet, I generated bitmap from user data. sometimes 25 or more lines.
Can I somehow clear memoryusages? and Init with need value actualy?
I thing so code it's unnecessary, but If you want/need write.
If I scrool too long app crashed on outOfmemory error
===================EDIT===================================
I I found out I generated new image on every touch (as it's the same)..
now increase less, but increase.
A best practice in Android for such cases would be to use a Recycler View with an Adapter. This will keep your memory in check.
https://developer.android.com/reference/android/support/v7/widget/RecyclerView.html
Also check out this great video from udacity
https://www.youtube.com/watch?v=-VPM6ICgCk8

Reusing Views when they are already assigned to the same element

In my app I'm displaying images on a grid view. In some cases there are a a lot of images on a single grid view (up to 1,000). This is driven off user data and is unavoidable.
It's impractical to load all images in memory. I tried that and was hitting memory errors fairly quickly. So to avoid this I create AsyncTasks in the getView() method of my array adaptor which load the image in the background. This works very smoothly so far.
The problem is that the set of images can change. notifyDataSetChanged() will trigger getView() to be called on every item on screen. The result is a lot of CPU time spent re-loading images which don't need to be changed.
Is there any way to detect if getView() is "reusing" a view to display the same element as it's already displaying? Alternatively is it possible to detect if an ImageView has already has a Bitmap assigned?

Images not loaded into ListView when scrolling fast

I have a long ListView in which there is an ImageView for each row. It displays the correct bitmaps if I slowly scroll the list (each row has different icon to show).
The problem comes up when I scroll the ListView fastly. It happens that many images are not loaded into their ImageView, leaving it transparent. Even the ones that were previously shown scrolling the list slowly.
Here is the code inside the getView() method that should display the icons:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
String name = ... //custom code to get the icon name to show
Bitmap bitmap = BitmapFactory.decodeFile(getIconsDir() + name + getIconsExt(), options);
holder.imgIcon.setImageBitmap(bitmap);
I'm recycling the convertView in the getView() method of the adapter.
I know for sure that the bitmap exists in that location.
imgIcon is the ImageView referenced by the ViewHolder of the row.
I've also tried to use image loaders (like Picasso) but I got the same result.
Does anyone have experienced this before?
Do not do bitmap decoding in adapter's getView(). It will Cause ListView to lag and also fill up RAM very fast.
You should:
Use a size limited, in-memory cache to hold onto bitmaps.
Decode and Load images in Views asynchronously.
ListView re-cycles the views, and device memory may not hold all the bitmaps loaded all the time. Even Image loading Libraries face that issue.
Yes, there are performance issues with images in ListViews.
But prefetching the images in any way is a could approach to avoid the calls to read operations on the file system and decoding of binary data.
I extinguish that you are storing your viewholder in the convertviews - tag.
Loading images from disk is a slow operation, and so is decoding them from whatever compressed format they're stored in (like JPG or PNG) into a Bitmap. So ideally, it shouldn't be done in getView() on the main thread. Also, they take up a lot of memory.
If these "icons" are static, you should just include them as drawable resources and then use ImageView.setImageResource. Then the OS will figure out how to load them most optimally (plus, that way you'll have the correct resolution for the given screen).
If the icons are not static (e.g. loaded from the network), I recommend using an in-memory cache with an asynchronous loader, but make sure it's limited in size and/or uses weak references (but beware: Android generally advises against using weak/soft references, especially for bitmaps, since the memory allocated for bitmaps is in native code, so the garbage collector doesn't know how much memory those images are really taking up and it may decide not to collect them even if it's running low on memory... because it thinks they're small).

Most efficient way to display a grid of images

What is the most efficient way to display a grid of random images on android?
I have a list of random album art images, I need to generate a grid out of them and use it as a background in my activity, the images are downloaded asynchronously, scaled down and cached, displaying them in a grid seems to consume a lot of RAM,(yes I'm recycling the bitmaps, and using LRU cache)
Would drawing them to a canvas be a better solution? Are there other efficient ways to do that?
Is the GridView safe, are there any guarantees that it won't run out of memory?
P.S. drawing them to a canvas would require me to redraw when the orientation or activity's size changes.
I donĀ“t think there is a more efficient way, at least I can not think of one right now. What you could do, that depends if grid view is necessary, is using the Image carousel from Romain Guy which is made in Renderscript. I do not have the URL at the moment but it is a google-code project.
Another page where sometime are good stuff for those things is http://www.theultimateandroidlibrary.com/all
The LRUCache is really nice and fast and should do the trick. I also would be interested in a more efficient way.....

Reclaiming memory from GridView Bitmaps that are off-screen and are not likely to be used

I have a GridView that I use to display images from an API.
The normal user behavior is to go to the bottom and pull more results.
I plan to scale the bitmaps down, but there will be many of them.
Therefore, I think it might be safe to delete images that are many pages above the current page.
Are the old images deleted by the GridView at some point?
The normal usage is to use the view cache, which looks like the GridView is holding on to them.

Categories

Resources