我想用Google API显示许多图标(超过2,000个图标)。我基于此tuto创建了一个简单的活动。
访问地图时显示没有任何问题图标。但是,当我放大/缩小几次时,java.lang.OutOfMemoryError:
12-16 08:48:29.415: E/dalvikvm-heap(606): 680640-byte external allocation too large for this process.
12-16 08:48:29.415: E/GraphicsJNI(606): VM won't let us allocate 680640 bytes
12-16 08:48:29.415: D/AndroidRuntime(606): Shutting down VM
12-16 08:48:29.415: W/dalvikvm(606): threadid=1: thread exiting with uncaught exception (group=0x4001d800)
12-16 08:48:29.425: E/AndroidRuntime(606): FATAL EXCEPTION: main
12-16 08:48:29.425: E/AndroidRuntime(606): java.lang.OutOfMemoryError: bitmap size exceeds VM budget
12-16 08:48:29.425: E/AndroidRuntime(606): at android.graphics.Bitmap.nativeCreate(Native Method)
12-16 08:48:29.425: E/AndroidRuntime(606): at android.graphics.Bitmap.createBitmap(Bitmap.java:468)
12-16 08:48:29.425: E/AndroidRuntime(606): at com.google.android.maps.ZoomHelper.createSnapshot(ZoomHelper.java:444)
12-16 08:48:29.425: E/AndroidRuntime(606): at com.google.android.maps.ZoomHelper.doZoom(ZoomHelper.java:151)
12-16 08:48:29.425: E/AndroidRuntime(606): at com.google.android.maps.ZoomHelper.doZoom(ZoomHelper.java:140)
12-16 08:48:29.425: E/AndroidRuntime(606): at com.google.android.maps.MapView.doZoom(MapView.java:1478)
12-16 08:48:29.425: E/AndroidRuntime(606): at com.google.android.maps.MapView.doZoom(MapView.java:1487)
12-16 08:48:29.425: E/AndroidRuntime(606): at com.google.android.maps.MapView$4.onClick(MapView.java:1381)
12-16 08:48:29.425: E/AndroidRuntime(606): at android.view.View.performClick(View.java:2408)
12-16 08:48:29.425: E/AndroidRuntime(606): at android.view.View$PerformClick.run(View.java:8816)
12-16 08:48:29.425: E/AndroidRuntime(606): at android.os.Handler.handleCallback(Handler.java:587)
12-16 08:48:29.425: E/AndroidRuntime(606): at android.os.Handler.dispatchMessage(Handler.java:92)
12-16 08:48:29.425: E/AndroidRuntime(606): at android.os.Looper.loop(Looper.java:123)
12-16 08:48:29.425: E/AndroidRuntime(606): at android.app.ActivityThread.main(ActivityThread.java:4627)
12-16 08:48:29.425: E/AndroidRuntime(606): at java.lang.reflect.Method.invokeNative(Native Method)
12-16 08:48:29.425: E/AndroidRuntime(606): at java.lang.reflect.Method.invoke(Method.java:521)
12-16 08:48:29.425: E/AndroidRuntime(606): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
12-16 08:48:29.425: E/AndroidRuntime(606): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
12-16 08:48:29.425: E/AndroidRuntime(606): at dalvik.system.NativeStart.main(Native Method)
这是我的活动方法:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
setContentView(R.layout.google_map);
Bundle bundle = getIntent().getExtras();
//MAP
mapView = (MapView) findViewById(R.id.mapView);
//zoom設定
LinearLayout zoomLayout = (LinearLayout)findViewById(R.id.zoom);
View zoomView = mapView.getZoomControls();
zoomLayout.addView(zoomView,
new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));
mapView.displayZoomControls(true);
//controller
mc = mapView.getController();
double[] adresse = (double[]) bundle.getDoubleArray(Site.LATTITUDE);
p = new GeoPoint((int) (adresse[0] * 1E6), (int) (adresse[1] * 1E6));
mc.animateTo(p);
mc.setZoom(18);
mapView.invalidate();
List<Overlay> listOfOverlays = mapView.getOverlays();
listOfOverlays.clear();
try {
//get datas from previous activiity
List<SiteGoogle> sitesList = bundle.getParcelableArrayList(Site.JSON_ARRAY);
//display message
Toast.makeText(getBaseContext(), getResources().getString(R.string.map_toad), Toast.LENGTH_LONG).show();
List<Overlay> mapOverlays = mapView.getOverlays();
mapOverlays.clear();
for(SiteGoogle site: sitesList) {
//set icon
Drawable drawable = this.getResources().getDrawable(R.drawable.icon01);
//icon setting
MapItemizedOverlay itemizedoverlay = new MapItemizedOverlay(drawable,this);
//geoPoint
GeoPoint point = new GeoPoint((int) (site.getLatitude() * 1E6), (int) (site.getLongitude() * 1E6));
//item
OverlayItem overlayitem = new OverlayItem(point, String.valueOf(site.getId()), null);
itemizedoverlay.addOverlay(overlayitem);
//add to map
mapOverlays.add(itemizedoverlay);
}
} catch(Exception e) {
Log.e(TAG,e.getMessage());
}
我的MapItemizedOverlay类:
@SuppressWarnings("rawtypes")
public class MapItemizedOverlay extends ItemizedOverlay {
private ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>();
private Context mContext;
public MapItemizedOverlay(Drawable defaultMarker, Context context) {
super(boundCenterBottom(defaultMarker));
mContext = context;
}
public void addOverlay(OverlayItem overlay) {
mOverlays.add(overlay);
populate();
}
@Override
protected OverlayItem createItem(int i) {
return mOverlays.get(i);
}
@Override
public int size() {
return mOverlays.size();
}
@Override
protected boolean onTap(int index){
OverlayItem item = mOverlays.get(index);
Intent intent = new Intent(mContext, SiteDetailsActivity.class);
intent.putExtra(Site.ID, Integer.parseInt(item.getTitle()));
mContext.startActivity(intent);
return true;
}
我不知道我能做些什么才能让它变得更快而不会崩溃。我应该使用画布还是缓存?我没有想法。
答案 0 :(得分:0)
我不确定它会有所帮助,但您在Overlay
的循环中每site
个sitesList
添加到地图中:
for(SiteGoogle site: sitesList){
//set icon
Drawable drawable = this.getResources().getDrawable(R.drawable.icon01);
//icon setting
MapItemizedOverlay itemizedoverlay = new MapItemizedOverlay(drawable,this);
//geoPoint
GeoPoint point = new GeoPoint((int) (site.getLatitude() * 1E6), (int) (site.getLongitude() * 1E6));
//item
OverlayItem overlayitem = new OverlayItem(point, String.valueOf(site.getId()), null);
itemizedoverlay.addOverlay(overlayitem);
//add to map
mapOverlays.add(itemizedoverlay);
}
所以你最终得到2000 Overlays和2000 Drawables,这并不好。
可以更有效地使用ItemizedOverlay
:
Drawable drawable = this.getResources().getDrawable(R.drawable.icon01);
MapItemizedOverlay itemizedoverlay = new MapItemizedOverlay(drawable,this);
for(SiteGoogle site: sitesList) {
GeoPoint point = new GeoPoint((int) (site.getLatitude() * 1E6), (int) (site.getLongitude() * 1E6));
OverlayItem overlayitem = new OverlayItem(point, String.valueOf(site.getId()), null);
itemizedoverlay.addOverlay(overlayitem);
}
mapOverlays.add(itemizedoverlay);
答案 1 :(得分:0)
正如Darth Beleg所说,我把“mapOverlays.add(itemizedoverlay)”放在循环之外,我改变了“mapView.invalidate()”的位置。但没有出现。
这个项目的死线是在几天之内,我今天必须解决这个问题。如果有人可以帮助我,我会很高兴。
活动的新代码:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
setContentView(R.layout.google_map);
//SearchActivity parameters
Bundle bundle = getIntent().getExtras();
//MAP
mapView = (MapView) findViewById(R.id.mapView);
//zoom設定
LinearLayout zoomLayout = (LinearLayout)findViewById(R.id.zoom);
View zoomView = mapView.getZoomControls();
zoomLayout.addView(zoomView,
new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));
mapView.displayZoomControls(true);
mc = mapView.getController();
double[] adresse = (double[]) bundle.getDoubleArray(Site.LATTITUDE);
p = new GeoPoint((int) (adresse[0] * 1E6), (int) (adresse[1] * 1E6));
mc.animateTo(p);
mc.setZoom(18);
//get current position
List<Overlay> listOfOverlays = mapView.getOverlays();
listOfOverlays.clear();
try{
//get icon position informations
List<SiteGoogle> sitesList = bundle.getParcelableArrayList(Site.JSON_ARRAY);
//message diplay
Toast.makeText(getBaseContext(), getResources().getString(R.string.map_toad), Toast.LENGTH_LONG).show();
List<Overlay> mapOverlays = mapView.getOverlays();
mapOverlays.clear();
MapItemizedOverlay itemizedoverlay = null;
for(SiteGoogle site: sitesList){
//set the icon
Drawable drawable;
switch (site.getCategory()){
case 1:
drawable = this.getResources().getDrawable(R.drawable.icon01);
break;
case 2:
drawable = this.getResources().getDrawable(R.drawable.icon02);
break;
case 3:
drawable = this.getResources().getDrawable(R.drawable.icon03);
break;
case 4:
drawable = this.getResources().getDrawable(R.drawable.icon04);
break;
case 5:
drawable = this.getResources().getDrawable(R.drawable.icon05);
break;
case 6:
drawable = this.getResources().getDrawable(R.drawable.icon06);
break;
case 7:
drawable = this.getResources().getDrawable(R.drawable.icon07);
break;
case 0:
drawable = this.getResources().getDrawable(R.drawable.icon00);
break;
default:
drawable = this.getResources().getDrawable(R.drawable.icon01);
break;
}
itemizedoverlay = new MapItemizedOverlay(drawable,this);
//geoPoint
GeoPoint point = new GeoPoint((int) (site.getLatitude() * 1E6), (int) (site.getLongitude() * 1E6));
//item
OverlayItem overlayitem = new OverlayItem(point, String.valueOf(site.getId()), null);
itemizedoverlay.addOverlay(overlayitem);
}
//add to map
mapOverlays.add(itemizedoverlay);
mapView.invalidate();
}catch(Exception e){
Log.e(TAG,e.getMessage());
}
}