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; } public void addRange(List<Location> locations) { for (Location l : locations) { addOne(l); } populate(); } public void add(Location location) { addOne(location); populate(); } 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);
Kurru source share