More efficient map overlays in Android
In my app I am drawing bus routes on top of a MapView. The routes have anywhere between a dozen and a few hundred GPS coordinates that describe the route that the bus takes.
The problem I'm having is that once I draw out all these lines panning/zooming the MapView
is incredibly slow (even clicking the 'Back' button t开发者_运维知识库akes a minute to happen).
I'm not sure how relevant it is, but I put in some debug code then checked the logcat output and the MapView
is repeatedly calling the draw()
method of the Overlay whether anything has changed or not. This is happening several times a second and is causing a massive amount of garbage collection to happen (2-3 MB every second).
Does anyone have any ideas/suggestions for a method to try and speed this up?
I have only used ItemizedOverlay
, not Overlay
, so these suggestions are pure conjecture. Heck, I haven't even done much with the 2D graphics API.
Obviously, the best answer is to get it to stop calling draw()
all the time. Try logging some stack traces and see if you can figure out what is triggering all of the draw()
calls. For example, in the Android Google Groups recently, somebody noticed that Chronometer
causes widgets in the same UI to be redrawn every second. While I can see you don't have a Chronometer
, you might be able to figure out some root cause to the draw()
calls that you can correct.
Assuming that does not help, I am guessing that the test for "whether anything has changed or not" is some combination of getLatitudeSpan()
, getLongitudeSpan()
, getZoomLevel()
, and maybe other MapView
methods. And, I am assuming that on every draw()
you are iterating over your GPS points and drawing the route. If so, you could try:
- When you really do draw, draw first to a
Canvas
backed by aBitmap
, then apply theBitmap
on theCanvas
you are handed indraw()
, and cache thatBitmap
. - Track what combination of values were used in the last
draw()
, and if the nextdraw()
is the same, just reuse the existingBitmap
. Else, go to step #1, making sure to release the Bitmap (or reuse it, if that's possible).
I am guessing that with graphics acceleration, blasting a Bitmap
onto the Canvas
is cheaper than iterating over the coordinates and drawing lines. And, by caching the Bitmap
, you will save on garbage generation.
Anyway, just a thought.
There are two draw methods in the overlay class. One with 3 arguments and one with 4 arguments. You have to override the draw method with 3 arguments. Overriding the method with 4 arguments will slow down your application. This is exactly, what happened to me. It seems, where are examples around in the internet with the same error.
精彩评论