Closed klattimer closed 11 years ago
Instead of modiyfing BitmapDecoderAssets, implement your own BitmapDecoder, and assign that to the TileView with TileView.setTileDecoder.
LMK if that's not clear or you need an example.
Yeah I realise that I can create my own BitmapDecoder however for the purposes of making it work exceptionally fast this made perfect sense (we already have a method of accessing inputstreams from the APKExtension package which is universally accessible via a singleton).
I will create my own bitmap decoder and probably call it BitmapDecoderExtensionAssets and will send it to you ;)
I'll also provide a supporting class which can provide the APK extension handling.
Regardless of how I'm performing the decode, it appears the ability of the TileView to load all the tiles is massively limited by the VM budget which appears to be much too small for what I'm trying to achieve. I've been looking at ways to improve the situation but I'm not able to find anything which is entirely helpful in this situation. Do you have any suggestions for how I might prevent the out of memory errors?
Some tips for avoiding OOM errors (specifically re: bitmap data)
FWIW, I've personally used this on 9 commercial apps, released into the wild, and dozens of apps for testing and debugging, and never get OOMs. I'm not saying it won't happen or you're doing something wrong necessarily, but for what it's worth I never see them.
HTH, LMK how it goes
Our tiles are 256x256 - and are as small sized as possible (indexed palette PNGs). Essentially the map is unable to load entirely in a lot of cases, throwing OOM errors. In the case of one of our maps we have hundreds of markers which are added to the map (and removed/re-added when zooming and panning) which is likely taking up more memory but that shouldn't be a huge amount.
The downsamples are pretty small, at 469x704 or 1056x704 depending on the orientation of the map. We're mostly seeing this on a galaxy S4 but the S3 is showing the same problem whereas the galaxy nexus isn't. I'm assuming that there's quite some variety between the VM size on these devices.
After spending some time with the code, I'm unable to find out where and how the bitmaps are being recycled which afaik is an important memory saving requirement according to: https://developer.android.com/training/displaying-bitmaps/manage-memory.html
If you could point me to where and how the destruction of tiles in memory is being handled there may be some improvements I can make to it.
The only alternative I have is to reduce the size of the tiles to 128x128 and hope that this will reduce the memory below the VM size just enough, however it seems more like the memory is being leaked as it works fine initially and after a few minutes it becomes almost impossible to avoid an OOM error.
Bitmaps are not recycled, they are nulled. If you recycle them, subsequent attempts to decode them will throw "bitmap was recycled" errors. The bitmaps are nulled in Tile.destroy
https://github.com/moagrius/TileView/blob/master/src/com/qozix/tileview/tiles/Tile.java#L88 Memory management is pretty aggressive, and it's been tested pretty thoroughly by a number of users in the previous widget with the issues you're describing. I think you're issue is elsewhere, but you're free to review and modify. I can't imagine it's leaking entire bitmaps - if it were I'd assume that any of the apps it's been in would have had similar problems.
At the start of every render pass, all tiles that don't have at least 1 pixel on-screen (including viewport padding) are scheduled to be destroyed. When the pass is complete, it re-calculates and runs again.
Assuming you're using tile sets as efficiently as possible, the only other thing I can suggest is to make sure you're cleaning up onPause and onDestroy, but if you're seeing the OOM during uninterrupted (non-onPaused) use, then that wouldn't directly apply. If you're issue is after a Pause event, then you definitely need to manage that manually in the Activity (method are provided but need to be invoked, e.g, TileView.clear
)
You might also try disabling tile transitions TileView.setTransitionsEnabled( false );
HTH, GL.
I've kinda gotten around this issue by adding largeHeap to the options in the manifest. I think the main reason for this occurring is that at the same time as we're loading the tiles, we're decompressing them from the obb file which is going to require the zip decompressor to be loaded too. I'd suggest making users aware of this in the future, if they're using extension packs, it's a good idea to use largeHeap :)
GTK. If you get a moment and want to write up some general info about using extension packs, I'll add it to the wiki.
can i close this issue?
I've adapted the BitmapDecoderAssets to enable it to access files which are stored in an APKExtension package (obb file) the maps we're using are 10000 by 6667 pixels in size and we have 6 of them totalling 300Mb of data. Loading tiles is slow, but with the downsample underneath is passable. However, not all tiles will successfully load the tiles which fail to load are usually towards the bottom and right but are essentially random.
Can you recommend anything which would improve this situation, e.g. adding a timed retry to load tiles?