MapView OutOfMemoryError Google API API Issues

I use the Google APIs MapView API in my Android app, and I found that it often encounters this error when I view and scale the map. They usually happen pretty quickly (20 seconds of using cards), so I think this will be a problem. Below is my stack. I am developing an HTC Desire that has 24 MB of memory.

Any ideas or tweaks I can make to reduce the frequency of these errors?

java.lang.OutOfMemoryError: bitmap size exceeds VM budget at android.graphics.Bitmap.nativeCreate(Native Method) at android.graphics.Bitmap.createBitmap(Bitmap.java:574) at com.google.android.maps.ZoomHelper.createSnapshot(ZoomHelper.java:444) at com.google.android.maps.ZoomHelper.doZoom(ZoomHelper.java:151) at com.google.android.maps.ZoomHelper.doZoom(ZoomHelper.java:140) at com.google.android.maps.MapView.doZoom(MapView.java:1478) at com.google.android.maps.MapView.doZoom(MapView.java:1487) at com.google.android.maps.MapView$6.onZoom(MapView.java:1442) at android.widget.ZoomButtonsController$3.onClick(ZoomButtonsController.java:268) at android.view.View.performClick(View.java:2408) at android.view.View$PerformClick.run(View.java:8817) at android.os.Handler.handleCallback(Handler.java:587) at android.os.Handler.dispatchMessage(Handler.java:92) at android.os.Looper.loop(Looper.java:144) at android.app.ActivityThread.main(ActivityThread.java:4937) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:521) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) at dalvik.system.NativeStart.main(Native Method) debug.heap native: allocated 10.63MB of 11.01MB (385.98KB free) debug.memory: allocated: 17.95MB of 24.00MB (13.50MB free) 

This is my overlay. I have about 50 elements in it displaying a 96x96 png image with some transparency (file size 6 KB).

 public class StationItemizedOverlay extends ItemizedOverlay<OverlayItem> { private ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>(); private ArrayList<Location> locations = new ArrayList<Location>(); private Context mContext; public StationItemizedOverlay(Drawable defaultMarker, Context context) { super(boundCenterBottom(defaultMarker)); this.mContext = context; } /** * Add a range of locations to this overlay * * @param locations The locations to add */ public void addRange(List<Location> locations) { for (Location l : locations) { addOne(l); } populate(); } /** * Add a location to this overlay * * @param location The location */ public void add(Location location) { addOne(location); populate(); } /** * Remove a location from this overlay * @param location The location to remove */ public void remove(Location location) { int position = locations.indexOf(location); if (position >= 0) { mOverlays.remove(position); locations.remove(position); populate(); } } private void addOne(Location location) { locations.add(location); int lat = location.getMicroLatitude(); int lon = location.getMicroLongitude(); GeoPoint point = new GeoPoint(lat, lon); OverlayItem item = new OverlayItem(point, location.getRealName(), location.getRealName()); mOverlays.add(item); } @Override protected boolean onTap(int index) { OverlayItem item = mOverlays.get(index); AlertDialog.Builder dialog = new AlertDialog.Builder(mContext); dialog.setTitle(item.getTitle()); dialog.setMessage(item.getSnippet()); dialog.show(); return true; } @Override protected OverlayItem createItem(int i) { return mOverlays.get(i); } @Override public int size() { return mOverlays.size(); } } 

This is my MapActivityClass.

 public class StationFinder extends MapActivity { IUIInterface dataInterface = UIInterfaceFactory.getInterface(); MapView mapView; List<Overlay> mapOverlays; Drawable drawable; StationItemizedOverlay trainItemizedOverlay; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.ui_station_finder); mapView = (MapView) findViewById(R.id.stationFinderUI_mapview); mapView.setBuiltInZoomControls(true); mapOverlays = mapView.getOverlays(); drawable = getResources().getDrawable(R.drawable.dash_train_btn_default); trainItemizedOverlay = new StationItemizedOverlay(drawable, this); myMapController = mapView.getController(); myMapController.setZoom(8); // zoom level selected from google map .com // center this location on northern ireland centerLocation(Settings.getNorthernIrelandCenter().getGeoPoint()); mapOverlays.add(trainItemizedOverlay); // add data to the adapters only whenever the data is loaded if (!dataInterface.isDataLoaded()) { // data is not loaded // so make a listener for the data loaded event dataLoadedListener = new IEventListener() { public void action(Object optionalData) { // the event has been triggered // register this function to run in the UI thread of the application runOnUiThread(new Runnable() { public void run() { dataLoaded(); } }); } }; // register the listener for data loaded events dataInterface.registerDataLoaded(dataLoadedListener); // call the data loaded function now incase the data has since been loaded by // the application between registering for the event if (dataInterface.isDataLoaded()) { dataLoaded(); } } else { // data already loaded so run immediately dataLoaded(); } } IEventListener dataLoadedListener = null; boolean isDataLoaded = false; private void dataLoaded() { // make sure this function is only called once if (isDataLoaded) return; isDataLoaded = true; // IMPORTANT STUFF GOES HERE trainItemizedOverlay.addRange(dataInterface.getAllLocations()); // clean up the data load listener if (dataLoadedListener != null) { dataInterface.removeDataLoaded(dataLoadedListener); dataLoadedListener = null; } } private MapController myMapController; private void centerLocation(GeoPoint center) { myMapController.animateTo(center); myMapController.setCenter(center); }; @Override protected boolean isRouteDisplayed() { return false; } 
+4
source share
2 answers

Strange this problem stopped. It is not clear why at present, although I believe that some other memory optimizations that I have made have made memory blocks more accessible for drawing a map.

+1
source

this should be due to the large number of overlays you have to use, and with one overlay with a larger image and no reuse. Although we can better answer if you post the code here too for our presentation ...

0
source

Source: https://habr.com/ru/post/1340614/


All Articles