Adam Varhegyi
Adam Varhegyi

Reputation: 9894

Adding OverlayItems to MapView is reallyslow, how to make it faster?

In my app there is a MapView, and I add OverlayItems to it, about 500, but it will be more even thousands in the future...

My problem is: When I switch to this Activity, I got a massive 3-4 sec blackout then it switches properly and I can navigate and tap on the map.

Some months ago when the app only contained 50-150 GeoPoints in the mapView there was no blackout. So i think something is wrong with my OverlayItem adding to the mapView, it really slows then the app.

I add my GeoPoints with a simple cycle on Activity startup.

What can i do to make this Activity faster and prevent the blackout?

EDIT:

Thanks to comments, i just realized i call populate() after every addOverlay(MyOverlayItem myoverlay) function call.

I edited the code, now after the cycle i call it only once by:

public void populateNow()
    {

        populate();

    }

But i just got a nice null pointer exception with this... Any ideas?

11-12 15:54:03.398: E/MapActivity(1534): Couldn't get connection factory client
11-12 15:54:03.531: E/AndroidRuntime(1534): FATAL EXCEPTION: main
11-12 15:54:03.531: E/AndroidRuntime(1534): java.lang.NullPointerException
11-12 15:54:03.531: E/AndroidRuntime(1534):     at com.google.android.maps.ItemizedOverlay.getIndexToDraw(ItemizedOverlay.java:211)
11-12 15:54:03.531: E/AndroidRuntime(1534):     at com.google.android.maps.ItemizedOverlay.draw(ItemizedOverlay.java:240)
11-12 15:54:03.531: E/AndroidRuntime(1534):     at com.google.android.maps.Overlay.draw(Overlay.java:179)
11-12 15:54:03.531: E/AndroidRuntime(1534):     at com.google.android.maps.OverlayBundle.draw(OverlayBundle.java:42)
11-12 15:54:03.531: E/AndroidRuntime(1534):     at com.google.android.maps.MapView.onDraw(MapView.java:530)
11-12 15:54:03.531: E/AndroidRuntime(1534):     at android.view.View.draw(View.java:6933)
11-12 15:54:03.531: E/AndroidRuntime(1534):     at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
11-12 15:54:03.531: E/AndroidRuntime(1534):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
11-12 15:54:03.531: E/AndroidRuntime(1534):     at android.view.ViewGroup.drawChild(ViewGroup.java:1644)
11-12 15:54:03.531: E/AndroidRuntime(1534):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
11-12 15:54:03.531: E/AndroidRuntime(1534):     at android.view.View.draw(View.java:6936)
11-12 15:54:03.531: E/AndroidRuntime(1534):     at android.widget.FrameLayout.draw(FrameLayout.java:357)
11-12 15:54:03.531: E/AndroidRuntime(1534):     at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
11-12 15:54:03.531: E/AndroidRuntime(1534):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
11-12 15:54:03.531: E/AndroidRuntime(1534):     at android.view.View.draw(View.java:6936)
11-12 15:54:03.531: E/AndroidRuntime(1534):     at android.widget.FrameLayout.draw(FrameLayout.java:357)
11-12 15:54:03.531: E/AndroidRuntime(1534):     at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1904)
11-12 15:54:03.531: E/AndroidRuntime(1534):     at android.view.ViewRoot.draw(ViewRoot.java:1527)
11-12 15:54:03.531: E/AndroidRuntime(1534):     at android.view.ViewRoot.performTraversals(ViewRoot.java:1263)
11-12 15:54:03.531: E/AndroidRuntime(1534):     at android.view.ViewRoot.handleMessage(ViewRoot.java:1865)
11-12 15:54:03.531: E/AndroidRuntime(1534):     at android.os.Handler.dispatchMessage(Handler.java:99)
11-12 15:54:03.531: E/AndroidRuntime(1534):     at android.os.Looper.loop(Looper.java:123)
11-12 15:54:03.531: E/AndroidRuntime(1534):     at android.app.ActivityThread.main(ActivityThread.java:3687)
11-12 15:54:03.531: E/AndroidRuntime(1534):     at java.lang.reflect.Method.invokeNative(Native Method)
11-12 15:54:03.531: E/AndroidRuntime(1534):     at java.lang.reflect.Method.invoke(Method.java:507)
11-12 15:54:03.531: E/AndroidRuntime(1534):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:842)
11-12 15:54:03.531: E/AndroidRuntime(1534):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
11-12 15:54:03.531: E/AndroidRuntime(1534):     at dalvik.system.NativeStart.main(Native Method)

Upvotes: 1

Views: 478

Answers (4)

Luis
Luis

Reputation: 12048

You may significantly improve ItemizedOverlay load time doing the following:

Trick 1:

This is the most important one. Ensure that you are not calling populate() every time you add one item. Instead, load all items and call populate() only once, after all items are loaded. This increase the load speed by a significant factor, and 1000 items should load in a few milliseconds.

Trick 2: If load still slows after the step above, probably the delay is comming from the place where you get the items to be loaded (sqlite, file, etc.). For example, loading 1000 items from a sqlite may take 3 to 4 seconds depending on your DB structure. To improve this one, you may redesign your DB structure or have the items loaded from DB in a AsyncTask.

Regards.

Upvotes: 3

Bhavesh Patadiya
Bhavesh Patadiya

Reputation: 25830

There is a limit to the number of overlay items that MapView can handle. There is no official word on what this limit is, but after some while, you will see sluggish behaviour during zoom/pan.

Some solutions are :

  1. MapviewOVerLay with Lazy Loading

  2. Load only as many markers that are visible, do this based on the zoom level and span.

  3. 10 overlays with 99 points are faster than 1 overlay with 900 points.

Upvotes: 1

Budius
Budius

Reputation: 39836

directly from the oficial guides: http://developer.android.com/guide/components/processes-and-threads.html

Any slow, blocking operations in an activity should be done in a new thread,
to avoid slowing down the user interface

with only 50 to 150 elements it was still processing fast enough so the UI wouldn't notice, but it was already a bad idea to do all that processing on the main UI thread.

I advice use Loaders, as they're a very clever system managed way of doing good background processing. http://developer.android.com/guide/components/loaders.html

Upvotes: 1

Ercan
Ercan

Reputation: 3705

Try to load your overlay items in a thread or asynctask and make them display as they loaded. this way you can stop blackout.But the overlays may be displayed with delay.

Upvotes: 3

Related Questions