Android Google API MapView OutOfMemory错误问题
我在Android应用程序中使用了谷歌API地图视图,我发现当我滚动和缩放地图时,它经常会遇到这个错误。它们往往发生得很快(使用地图20秒),所以我认为这将是一个问题。下面是我的追踪。我正在开发HTC Desire,它有24MB的内存空间 我能做些什么来减少这些错误的发生频率Android Google API MapView OutOfMemory错误问题,android,google-maps,out-of-memory,Android,Google Maps,Out Of Memory,我在Android应用程序中使用了谷歌API地图视图,我发现当我滚动和缩放地图时,它经常会遇到这个错误。它们往往发生得很快(使用地图20秒),所以我认为这将是一个问题。下面是我的追踪。我正在开发HTC Desire,它有24MB的内存空间 我能做些什么来减少这些错误的发生频率 java.lang.OutOfMemoryError: bitmap size exceeds VM budget at android.graphics.Bitmap.nativeCreate(Native Me
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)
这是我的套印。我有大约50个项目在它显示一个png图像96x96与一些透明度(6KB的文件大小)
公共类StationizedOverlay扩展了ItemizedOverlay
{
private ArrayList mOverlays=new ArrayList();
私有ArrayList位置=新建ArrayList();
私有上下文;
公共StationizedOverlay(可绘制的defaultMarker,上下文)
{
super(boundCenterBottom(defaultMarker));
this.mContext=上下文;
}
/**
*将一系列位置添加到此覆盖
*
*@param locations要添加的位置
*/
公共void addRange(列出位置)
{
对于(位置l:位置)
{
addOne(l);
}
填充();
}
/**
*将位置添加到此覆盖
*
*@param location指定位置
*/
公共作废添加(位置)
{
addOne(位置);
填充();
}
/**
*从此覆盖中删除一个位置
*@param location要删除的位置
*/
公共空间移除(位置)
{
int位置=位置。indexOf(位置);
如果(位置>=0)
{
mOverlays.移除(位置);
位置。移除(位置);
填充();
}
}
私有void addOne(位置)
{
位置。添加(位置);
int lat=location.getMicroLatitude();
int lon=location.getMicroLongitude();
地质点=新的地质点(纬度、经度);
OverlayItem item=新的OverlayItem(点,location.getRealName(),location.getRealName());
添加(项目);
}
@凌驾
受保护的布尔onTap(整数索引)
{
OverlayItem item=mOverlays.get(索引);
AlertDialog.Builder dialog=新建AlertDialog.Builder(mContext);
setTitle(item.getTitle());
setMessage(item.getSnippet());
dialog.show();
返回true;
}
@凌驾
受保护的OverlayItem createItem(int i)
{
返回mOverlays.get(i);
}
@凌驾
公共整数大小()
{
返回mOverlays.size();
}
}
这是我的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;
}
公共类StationFinder扩展了MapActivity
{
IUIInterface dataInterface=UIInterfaceFactory.getInterface();
地图视图;
列出地图覆盖图;
可拉伸;
StationizedOverlay培训项目化Overlay;
@凌驾
创建时受保护的void(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.ui\u station\u finder);
mapView=(mapView)findViewById(R.id.StationInderUI\u mapView);
mapView.SetBuilTinZoomControl(真);
mapOverlays=mapView.getOverlays();
drawable=getResources().getDrawable(R.drawable.dash\u train\u btn\u默认值);
Trainiitemizedoverlay=新桩号mizedoverlay(可拉深,此);
myMapController=mapView.getController();
myMapController.setZoom(8);//从google map.com选择缩放级别
//以北爱尔兰为中心
中心位置(Settings.getNorthernRelandCenter().getGeoPoint());
mapOverlays.add(TrainiItemizeOverlay);
//仅在加载数据时向适配器添加数据
如果(!dataInterface.isDataLoaded())
{
//未加载数据
//因此,为数据加载事件创建一个侦听器
dataLoadedListener=新的IEventListener()
{
公共作废操作(对象可选数据)
{
//事件已被触发
//注册此函数以在应用程序的UI线程中运行
runOnUiThread(新的Runnable()
{
公开募捐
{
数据加载();
}
});
}
};
//注册数据加载事件的侦听器
dataInterface.registerDataLoaded(dataLoadedListener);
//如果数据已由加载,请立即调用数据加载函数
//注册事件之间的应用程序
if(dataInterface.isDataLoaded())
{
数据加载();
}
}
其他的
{
//数据已加载,请立即运行
数据加载();
}
}
IEventListener dataLoadedListener=null;
布尔值isDataLoaded=false;
私有void dataLoaded()
{
//确保此函数只调用一次
如果(isDataLoaded)
返回;
isDataLoaded=true;
//这里有重要的东西
trainiitemizedoverlay.addRange(dataInterface.getAllLocations());
//清理数据加载侦听器
如果(dataLoadedListener!=null)
{
dataInterface.removeDataLoaded(dataLoadedListener);
dataLoadedListener=null;
}
}
私有映射控制器myMapController;
专用空心中心位置(地质点中心)
{
myMapController.animateTo(中心);
myMapController.setCenter(center);
};
@凌驾
受保护的布尔值isRouteDisplayed()
{
返回false;
}
这一定是由于您必须使用大量的覆盖层,以及单个覆盖层具有较大尺寸的图像,并且不可绘制重用
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;
}