Pregunta

I have a lot of markers (1700 or more) loading on a Google Map v2 in Android. I would like to cut down on the amount of memory being used creating this map as it seems to be FC my 2.3 Droid. I would like to add points only if they are within the visible screen area.

I have looked at the Google Maps Extension and see this:

map.setClustering(new ClusteringSettings().enabled(false).addMarkersDynamically(true));

However my for loop adds all the markers to the map. How do I set this up and only add my markers per this method?

Here is my for loop adding markers:

int nsize = visibleMarkers.size();
                for (int i = 0; i < nsize; i++) {
                    MapMarkers marks = new MapMarkers();
                    String title = visibleMarkers.valueAt(i).getTitle();
                    String desc = visibleMarkers.valueAt(i).getDesc();
                    Float latitude = visibleMarkers.valueAt(i).getLat();
                    Float longitude = visibleMarkers.valueAt(i).getLon();

                    m = map.addMarker(new MarkerOptions()
                            .position(new LatLng(latitude, longitude))
                            .title(title)
                            .icon(BitmapDescriptorFactory
                                    .fromResource(R.drawable.snotel_marker)));

                    marks.setTitle(title);
                    marks.setDesc(desc);

                    markerInfo.put(m, marks);

                    map.setOnInfoWindowClickListener(new OnInfoWindowClickListener() {
                        @Override
                        public void onInfoWindowClick(Marker marker) {

                            MapMarkers markInfo = markerInfo.get(marker);

                            Intent i = new Intent(MainActivity.this,
                                    MarkerInformation.class);
                            i.putExtra("name", markInfo.getTitle()).putExtra(
                                    "description", markInfo.getDesc());
                            i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                            startActivity(i);

                        }

                    });
                }

How do I add them only when the area in the screen is shown. Will this cut down on resources use on my device?

EDIT::: Here is logcat issues

10-01 10:59:41.590: D/dalvikvm(6488): GC_FOR_MALLOC freed <1K, 55% free 10009K/21895K, external 2433K/2688K, paused 94ms
10-01 10:59:41.691: D/dalvikvm(6488): GC_FOR_MALLOC freed 128K, 55% free 9913K/21895K, external 2433K/2688K, paused 72ms
10-01 10:59:41.793: D/dalvikvm(6488): GC_FOR_MALLOC freed 62K, 55% free 9973K/21895K, external 2433K/2688K, paused 83ms
10-01 10:59:41.910: D/dalvikvm(6488): GC_FOR_MALLOC freed 65K, 55% free 10026K/21895K, external 2433K/2688K, paused 74ms
10-01 10:59:41.988: D/dalvikvm(6488): GC_FOR_MALLOC freed 0K, 54% free 10085K/21895K, external 2433K/2688K, paused 72ms
10-01 10:59:41.988: I/dalvikvm-heap(6488): Grow heap (frag case) to 14.703MB for 60434-byte allocation
10-01 10:59:42.082: D/dalvikvm(6488): GC_FOR_MALLOC freed 0K, 54% free 10144K/21959K, external 2433K/2688K, paused 82ms
10-01 10:59:42.199: D/dalvikvm(6488): GC_FOR_MALLOC freed 138K, 55% free 10043K/21959K, external 2433K/2688K, paused 82ms
10-01 10:59:42.207: I/dalvikvm-heap(6488): Grow heap (frag case) to 14.762MB for 164912-byte allocation
10-01 10:59:42.277: D/dalvikvm(6488): GC_FOR_MALLOC freed 8K, 54% free 10196K/22151K, external 2433K/2688K, paused 68ms
10-01 10:59:42.730: D/dalvikvm(6488): GC_FOR_MALLOC freed 509K, 55% free 10017K/22151K, external 2433K/2688K, paused 72ms
10-01 10:59:42.879: D/dalvikvm(6488): GC_FOR_MALLOC freed 364K, 55% free 10066K/22151K, external 2433K/2688K, paused 78ms
10-01 10:59:42.988: D/dalvikvm(6488): GC_FOR_MALLOC freed 39K, 55% free 10117K/22151K, external 2433K/2688K, paused 82ms
10-01 10:59:42.988: I/dalvikvm-heap(6488): Forcing collection of SoftReferences for 201280-byte allocation
10-01 10:59:43.082: D/dalvikvm(6488): GC_FOR_MALLOC freed 8K, 55% free 10108K/22151K, external 2433K/2688K, paused 86ms
10-01 10:59:43.082: E/dalvikvm-heap(6488): Out of memory on a 201280-byte allocation.
10-01 10:59:43.082: I/dalvikvm(6488): "vts_com.jasonflaherty.snoteldata" prio=5 tid=10 RUNNABLE
10-01 10:59:43.082: I/dalvikvm(6488):   | group="main" sCount=0 dsCount=0 obj=0x405c8fe0 self=0x1c1ec0
10-01 10:59:43.082: I/dalvikvm(6488):   | sysTid=6533 nice=10 sched=0/0 cgrp=bg_non_interactive handle=1628832
10-01 10:59:43.082: I/dalvikvm(6488):   at maps.ao.d.a((null):~-1)
10-01 10:59:43.082: I/dalvikvm(6488):   at maps.i.cu.a((null):-1)
10-01 10:59:43.082: I/dalvikvm(6488):   at maps.k.ah.a((null):-1)
10-01 10:59:43.082: I/dalvikvm(6488):   at maps.k.d.a((null):-1)
10-01 10:59:43.082: I/dalvikvm(6488):   at maps.k.g.handleMessage((null):-1)
10-01 10:59:43.082: I/dalvikvm(6488):   at android.os.Handler.dispatchMessage(Handler.java:99)
10-01 10:59:43.082: I/dalvikvm(6488):   at android.os.Looper.loop(Looper.java:130)
10-01 10:59:43.082: I/dalvikvm(6488):   at maps.k.d.c((null):-1)
10-01 10:59:43.082: I/dalvikvm(6488):   at maps.k.ag.c((null):-1)
10-01 10:59:43.082: I/dalvikvm(6488):   at maps.ao.b.run((null):-1)
10-01 10:59:43.129: W/dalvikvm(6488): threadid=10: thread exiting with uncaught exception (group=0x40015560)
10-01 10:59:43.144: E/AndroidRuntime(6488): FATAL EXCEPTION: vts_com.jasonflaherty.snoteldata
10-01 10:59:43.144: E/AndroidRuntime(6488): java.lang.OutOfMemoryError
10-01 10:59:43.144: E/AndroidRuntime(6488):     at maps.ao.d.a(Unknown Source)
10-01 10:59:43.144: E/AndroidRuntime(6488):     at maps.i.cu.a(Unknown Source)
10-01 10:59:43.144: E/AndroidRuntime(6488):     at maps.k.ah.a(Unknown Source)
10-01 10:59:43.144: E/AndroidRuntime(6488):     at maps.k.d.a(Unknown Source)
10-01 10:59:43.144: E/AndroidRuntime(6488):     at maps.k.g.handleMessage(Unknown Source)
10-01 10:59:43.144: E/AndroidRuntime(6488):     at android.os.Handler.dispatchMessage(Handler.java:99)
10-01 10:59:43.144: E/AndroidRuntime(6488):     at android.os.Looper.loop(Looper.java:130)
10-01 10:59:43.144: E/AndroidRuntime(6488):     at maps.k.d.c(Unknown Source)
10-01 10:59:43.144: E/AndroidRuntime(6488):     at maps.k.ag.c(Unknown Source)
10-01 10:59:43.144: E/AndroidRuntime(6488):     at maps.ao.b.run(Unknown Source)
10-01 10:59:43.394: D/dalvikvm(6488): GC_FOR_MALLOC freed 195K, 55% free 10116K/22151K, external 2433K/2688K, paused 153ms
10-01 10:59:43.433: W/ResourceType(6488): getEntry failing because entryIndex 939 is beyond type entryCount 1
10-01 10:59:43.433: W/ResourceType(6488): Failure getting entry for 0x7f0b03ab (t=10 e=939) in package 0 (error -2147483647)
10-01 10:59:43.433: E/GooglePlayServicesUtil(6488): The Google Play services resources were not found. Check your project configuration to ensure that the resources are included.
10-01 10:59:43.769: D/dalvikvm(6488): GC_EXTERNAL_ALLOC freed 115K, 55% free 10102K/22151K, external 2433K/2688K, paused 121ms
10-01 10:59:43.824: E/dalvikvm-heap(6488): 80-byte external allocation too large for this process.
10-01 10:59:43.824: W/OSMemory(6488): External allocation of 80 bytes was rejected
10-01 10:59:43.925: D/dalvikvm(6488): GC_FOR_MALLOC freed <1K, 55% free 10102K/22151K, external 2433K/2688K, paused 101ms
10-01 10:59:44.019: W/dalvikvm(6488): threadid=17: thread exiting with uncaught exception (group=0x40015560)
10-01 10:59:44.027: I/Process(6488): Sending signal. PID: 6488 SIG: 9
¿Fue útil?

Solución

How do I set this up and only add my markers per this method?

Google Maps Extension's

map.setClustering(new ClusteringSettings().enabled(false).addMarkersDynamically(true));

method does exactly that. Adds only Markers in visible region to the map. All markers outside of it are kept by Extensions lib, but no interprocess communication is made in order to put them on the map. They will be added when user scrolls to show different region.

If you think it's something wrong with the map, first thing I would try would be using default marker icon or creating only one BitmapDescriptor for all Markers:

BitmapDescriptor icon = BitmapDescriptorFactory.fromResource(R.drawable.snotel_marker));
for (int i = 0; i < nsize; i++) {
    // ...
    m = map.addMarker(new MarkerOptions()
                        .position(new LatLng(latitude, longitude))
                        .title(title)
                        .icon(icon);
    // ...
}

This should solve OutOfMemoryError issues.


Other than that, you don't want to call setOnInfoWindowClickListener in a loop. Once is more than enough.
And one more thing: if that's all data you want to keep, you may use MarkerOptions.snippet and Marker.getSnippet for your String desc. No need to keep it all in Map<Marker, MapMarkers> data structure. If you want to keep additional data beside two Strings and LatLng, I suggest using MarkerOptions.data(marks) (since 1.6) or Marker.setData(marks) in Extensions lib. To read it later in OnInfoWindowClickListener callback:

MapMarkers marks = (MapMarkers) marker.getData();
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top