我有一个应用程序可以放下标记并保存它。我也使用mylocationoverlay来显示用户当前位置。该应用程序大部分时间都可以工作,在测试过程中似乎运行正常。然而,当我在手机上使用它时,如果我试图同时拥有太多的引脚(超过500),它就会崩溃。我想知道我们允许的叠加数量是否有限制,或者我的程序是否有其他问题
这是我的Map类,我在重载函数中添加了引脚(从网络服务器收集),mylocationoverlay在oncreate方法中。
PS,我注意到每次调用函数重新加载时,之前的叠加都不会消失。我应该再次添加引脚之前调用removeAllViews吗?感谢
public class Maps extends MapActivity {
private MapView mapView = null;
private MyLocationOverlay myLocationOverlay = null;
ProgressDialog progressDialog;
private ArrayList<Pins> mList;
final public static int[] pincolorstar = { R.drawable.pinredstar,
R.drawable.pinlitebluestar, R.drawable.pinblackstar,
R.drawable.pindarkbluestar, R.drawable.pingreenstar,
R.drawable.pinlitegreenstar, R.drawable.pinorangestar,
R.drawable.pinyellowstar, R.drawable.pinwhitestar,
R.drawable.pinpurplestar };
static boolean setSatellite, setHybrid = false;
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
myLocationOverlay.disableMyLocation();
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
myLocationOverlay.enableMyLocation();
}
@Override
protected void onCreate(Bundle icicle) {
// TODO Auto-generated method stub
super.onCreate(icicle);
try {
setContentView(R.layout.maps);
} catch (Exception e) {
e.printStackTrace();
}
final SharedPreferences prefs = getSharedPreferences("Settings", 0);
final int hour = prefs.getInt("Hour_Range", 4);
mapView = (MapView) findViewById(R.id.mapView);
myLocationOverlay = new MyLocationOverlay(Maps.this, mapView);
mapView.getOverlays().add(myLocationOverlay);
new Reload().execute();
Button done = (Button) findViewById(R.id.btnDone);
done.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
Button change = (Button) findViewById(R.id.btnChangeTime);
change.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
final int hour = prefs.getInt("Hour_Range", 4);
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.your_dialog,
(ViewGroup) findViewById(R.id.relativeLayoutMaps));
final SeekBar seekBar = (SeekBar) layout
.findViewById(R.id.seekBarChangeTime);
final TextView ChangeTexthour = (TextView) layout
.findViewById(R.id.tVChangeableTime);
ChangeTexthour.setText(prefs.getString("Hour_notification",
"Only most recent positions"));
seekBar.setProgress(hour);
OnSeekBarChangeListener yourSeekBarListener = new OnSeekBarChangeListener() {
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onProgressChanged(SeekBar seekBar,
int progress, boolean fromUser) {
ChangeTexthour
.setText(getResources()
.getString(
R.string.showlocationsforthelastxhours1)
+ " "
+ progress
+ " "
+ getResources()
.getString(
R.string.showlocationsforthelastxhours2));
}
};
seekBar.setOnSeekBarChangeListener(yourSeekBarListener);
AlertDialog.Builder builder = new AlertDialog.Builder(Maps.this)
.setView(layout)
.setPositiveButton(
getResources().getString(R.string.Cancel), null)
.setNegativeButton("Set",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
SharedPreferences.Editor editor = prefs
.edit();
editor.putString(
"Hour_notification",
getResources()
.getString(
R.string.showlocationsforthelastxhours1)
+ " "
+ seekBar.getProgress()
+ " "
+ getResources()
.getString(
R.string.showlocationsforthelastxhours2));
editor.putInt("Hour_Range",
seekBar.getProgress());
editor.commit();
new Reload().execute();
}
});
AlertDialog alertDialog = builder.create();
alertDialog.show();
}
});
Button displayChange = (Button) findViewById(R.id.btnDisplayChange);
displayChange.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
AlertDialog.Builder builder = new AlertDialog.Builder(Maps.this)
.setMessage("Map Display Mode")
.setPositiveButton("Map",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
setSatellite = false;
setHybrid = false;
new Reload().execute();
}
})
.setNeutralButton("Satellite",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
setSatellite = true;
setHybrid = false;
new Reload().execute();
}
})
.setNegativeButton("Hybrid",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
setHybrid = true;
setSatellite = false;
new Reload().execute();
}
});
AlertDialog alertDialog = builder.create();
alertDialog.show();
}
});
}
@Override
protected boolean isRouteDisplayed() {
return false;
}
private class Pins {
private String name;
private String time;
private String id;
private boolean mostrecent;
private Double longitude;
private Double latitude;
public Pins(String time, String id, String mostrecent,
Double longitude, Double latitude) {
this.time = time;
this.id = id;
this.longitude = longitude;
this.latitude = latitude;
boolean active = false;
if (mostrecent.equals("1"))
active = true;
else
active = false;
this.mostrecent = active;
}
public String getName() {
return name;
}
public String getTime() {
return time;
}
public String getId() {
return id;
}
public boolean getMostRecent() {
return mostrecent;
}
public Double getLongitude() {
return longitude;
}
public Double getLatitude() {
return latitude;
}
public void setName(String name) {
this.name = name;
}
}
public class Reload extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... params) {
final SharedPreferences prefs = getSharedPreferences("Settings", 0);
final int hour = prefs.getInt("Hour_Range", 4);
int followsize = 0;
for (int i = 0; i < ImTracking.ping.length; i++) {
followsize += ImTracking.ping[i];
}
String[] ids = new String[followsize];
int counter = 0;
for (int i = 0; i < ImTracking.ping.length; i++) {
if (ImTracking.ping[i] == 1) {
ids[counter] = ImTracking.pList.get(i).getid();
counter++;
}
}
JSONArray users = new JSONArray(Arrays.asList(ids));
HttpParams httpParams = new BasicHttpParams();
// 30seconds and it stops
HttpConnectionParams.setConnectionTimeout(httpParams, 30000);
HttpConnectionParams.setSoTimeout(httpParams, 30000);
DefaultHttpClient httpclient = new DefaultHttpClient(httpParams);
HttpPost httpost = new HttpPost(
"https://iphone-radar.com/gps/gps_locations_fetch");
JSONObject holder = new JSONObject();
try {
holder.put("userids", users);
holder.put("range", hour);
Calendar c = Calendar.getInstance();
TimeZone tz = c.getTimeZone();
Date now = new Date();
int offsetFromUtc = tz.getOffset(now.getTime()) / 1000;
holder.put("timezone", offsetFromUtc);
StringEntity se = new StringEntity(holder.toString());
httpost.setEntity(se);
httpost.setHeader("Accept", "application/json");
httpost.setHeader("Content-type", "application/json");
ResponseHandler responseHandler = new BasicResponseHandler();
String response = httpclient.execute(httpost, responseHandler);
org.json.JSONObject obj = new org.json.JSONObject(response);
JSONArray tracking_users = obj.getJSONArray("d");
ArrayList<Pins> mList = new ArrayList<Pins>();
int minLat = Integer.MAX_VALUE;
int maxLat = Integer.MIN_VALUE;
int minLon = Integer.MAX_VALUE;
int maxLon = Integer.MIN_VALUE;
for (int i = 0; i < tracking_users.length(); i++) {
JSONObject user = tracking_users.getJSONObject(i);
Pins pin = new Pins(user.getString("time"),
user.getString("user_id"),
user.getString("most_recent"),
user.getDouble("longitude"),
user.getDouble("latitude"));
maxLat = (int) Math.max(user.getDouble("latitude") * 1E6,
maxLat);
minLat = (int) Math.min(user.getDouble("latitude") * 1E6,
minLat);
maxLon = (int) Math.max(user.getDouble("longitude") * 1E6,
maxLon);
minLon = (int) Math.min(user.getDouble("longitude") * 1E6,
minLon);
mList.add(pin);
}
mapView.setSatellite(setSatellite);
mapView.setStreetView(setHybrid);
List<Overlay> mapOverlays = mapView.getOverlays();
for (int i = 0; i < mList.size(); i++) {
Drawable drawable = null;
for (int k = 0; k < ImTracking.pList.size(); k++) {
if (mList.get(i).getId()
.equals(ImTracking.pList.get(k).getid())) {
mList.get(i).setName(
ImTracking.pList.get(k).getName());
if (mList.get(i).getMostRecent()) {
drawable = Maps.this.getResources()
.getDrawable(
pincolorstar[ImTracking.pList
.get(k).getPosition()]);
} else {
drawable = Maps.this
.getResources()
.getDrawable(
ImTracking.pincolors[ImTracking.pList
.get(k).getPosition()]);
}
}
}
HelloItemizedOverlay itemizedoverlay = new HelloItemizedOverlay(
drawable, mapView);
GeoPoint myPoint = new GeoPoint((int) (mList.get(i)
.getLatitude() * 1E6), (int) (mList.get(i)
.getLongitude() * 1E6));
OverlayItem overlayitem = new OverlayItem(myPoint, mList
.get(i).getName(), mList.get(i).getTime());
itemizedoverlay.addOverlay(overlayitem);
mapOverlays.add(itemizedoverlay);
}
MapController mc = mapView.getController();
mc.zoomToSpan(Math.abs(maxLat - minLat),
Math.abs(maxLon - minLon));
mc.animateTo(new GeoPoint((maxLat + minLat) / 2,
(maxLon + minLon) / 2));
} catch (Exception e) {
e.printStackTrace();
}
progressDialog.dismiss();
return null;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = ProgressDialog.show(Maps.this, "",
"Updating Data...");
}
}
}
答案 0 :(得分:4)
每个只有一个引脚,不应该有500个覆盖。你应该拥有的只有两个叠加层。一个是MyLocationOverlay,另一个是ItemizedOverlay。
ItemizedOverlay可以容纳多个引脚。你应该把下面一行放在循环之外。
mapOverlays.add(itemizedoverlay);
另请参阅OverlayItem setMarker()为单个项目设置Drawable,这样您就不必创建多个叠加层。
更确切地说:
// take this out from the loop since you only need one
HelloItemizedOverlay itemizedoverlay = new HelloItemizedOverlay(drawable, mapView);
for (int i = 0; i < mList.size(); i++) {
... the rest of the code
GeoPoint myPoint = new GeoPoint((int) (mList.get(i)
.getLatitude() * 1E6), (int) (mList.get(i)
.getLongitude() * 1E6));
OverlayItem overlayitem = new OverlayItem(myPoint, mList
.get(i).getName(), mList.get(i).getTime());
// set the drawable here for each item instead of setting it for each Overlay
overlayitem.setMarker(drawable);
itemizedoverlay.addOverlay(overlayitem);
}
// take this one out the loop. ItemizedOverlay can handle multiple items
// you don't have to create multiple ItemizedOverlay for each pin
mapOverlays.add(itemizedoverlay);