Android Google API MapView OutOfMemory错误问题

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

我在Android应用程序中使用了谷歌API地图视图,我发现当我滚动和缩放地图时,它经常会遇到这个错误。它们往往发生得很快(使用地图20秒),所以我认为这将是一个问题。下面是我的追踪。我正在开发HTC Desire,它有24MB的内存空间

我能做些什么来减少这些错误的发生频率

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;
    }