Android 地图缩放 - OutOfMemory
当我在地图活动中不时放大/缩小时,我会在控制台中收到“内存不足错误:位图大小超出虚拟机预算”。该应用程序不会在我的开发手机上崩溃,但我不确定这个问题将来是否不会造成问题。
注意:我在地图上最多显示 30 个自定义标记。
错误堆栈没有引用我的代码。有没有人有解决办法或最佳实践来消除此错误?
提前致谢。
public void onCreate(Bundle savedInstanceState) {
...
marker = getResources().getDrawable(R.drawable.marker);
...
fillData();
}
public void fillData() {
...
for (int i = 0; i < lats.length; i++) {
...
map.getOverlays().add(new ContactOverlay(marker, tempLat, tempLon, names[i],
phones[i]));
}
}
private class ContactOverlay extends ItemizedOverlay<OverlayItem> {
private List<OverlayItem> items = new ArrayList<OverlayItem>();
public ContactOverlay(Drawable marker, double latitude,
double longitude, String title, String snippet) {
super(marker);
boundCenterBottom(marker);
items.add(new OverlayItem(getPoint(longitude, latitude), title,
snippet));
populate();
}
@Override
protected OverlayItem createItem(int i) {
return (items.get(i));
}
...
}
When I zoom in/zoom out from time to time in my map activity I get in console an "OutOfMemory error:bitmap size exceeds VM budget". The app doesn't crash on my developement phone, but I'm not sure If this issue won't cause a problem in future.
Note: I display maximum 30 custom markers on map.
The error stack doesn't reference my code. Does anyone have a fix or a best practice to get rid of this error?
Thanks in advance.
public void onCreate(Bundle savedInstanceState) {
...
marker = getResources().getDrawable(R.drawable.marker);
...
fillData();
}
public void fillData() {
...
for (int i = 0; i < lats.length; i++) {
...
map.getOverlays().add(new ContactOverlay(marker, tempLat, tempLon, names[i],
phones[i]));
}
}
private class ContactOverlay extends ItemizedOverlay<OverlayItem> {
private List<OverlayItem> items = new ArrayList<OverlayItem>();
public ContactOverlay(Drawable marker, double latitude,
double longitude, String title, String snippet) {
super(marker);
boundCenterBottom(marker);
items.add(new OverlayItem(getPoint(longitude, latitude), title,
snippet));
populate();
}
@Override
protected OverlayItem createItem(int i) {
return (items.get(i));
}
...
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
尝试重用位图和您绘制的画布。每次重绘叠加层时,都会分配一个新的位图。
Try to reuse the bitmap and the canvas where you draw. Each time when you redraw the overlay, a new bitmap is allocated.
@dorin,我发布了一个答案,因为答案太长了。
我觉得还好,但这不是问题。
每次重绘覆盖时,都会创建一个新的位图。您看不到它,因为这是在 onDraw 方法中发生的,而覆盖是这样做的。因此,假设您重绘了叠加层 10 次。创建了 10 个位图。如果 GC 不清理这 10 个位图,当您创建下一个位图时,操作系统将尝试为新位图分配内存。如果堆中没有足够的内存,则会抛出异常,然后 GC 释放为前 10 个位图分配的内存。您要做的就是避免这种位图内存分配。创建覆盖基类并扩展 ItemizedOverlay。重写 onDraw() 方法并创建位图字段。每次调用 onDraw() 时,都会回收位图并在其上再次绘制。通过这种方式,您可以避免重新创建新的位图 ->也有 OutOfMemory 异常
@dorin, I post an answer because the answer is too long.
I think it is ok, but this is not the problem.
Each time when you redraw the overlay a new bitmap is created.You can not see it, because this happens in onDraw method and the overlay do it. So, lets imagine you redraw the overlay 10 times. 10 bitmaps are created. If the GC do not clean this 10 bitmaps, when you create the next one, the OS is trying to allocate memory for new bitmap. If there is not enough memory in the heap, an exception is thrown and then GC frees the memory that was allocated for the previous 10 bitmaps. The thing you have to do is to avoid this bitmap memory allocation. Create base overlay class and extend the ItemizedOverlay. Override the onDraw() Method and create a bitmap field. Each time onDraw() is called, recycle the bitmap and draw again on it. On this way you avoid a new bitmap recreation -> OutOfMemory exception too