我的应用程序必须从 android 的内部 sqlite 数据库加载一些“点”,并将这些点转换为 map 上的线,然后,从数据库中,我加载其他“点”成为 map 上的标记。
问题是上面描述的加载过程非常慢。这个过程可能需要很多秒,在最坏的情况下也可能需要几分钟。
数据库中的点来自跟踪您的位置的服务。我在此服务中实现了一些方法来避免点过多,例如时间控制(如果两个后续点的时间太近,第二个不保存),位置控制(如果两个后续点具有相同的坐标,最后一个将不会被保存)和距离检查(如果两个后续点的距离太近,最后一个将不会被保存)。
在加载过程中,其他计算可能会在这些点上发生,但在最好的情况下也会出现缓慢,这只是从数据库中读取数据。
这是我创建数组的地方,其中包含用于在 map 上绘制线的点。
public BuildPointsList(Context context, long travelId) {
this.context=context;
this.travelId = travelId;
initializePointList();
}
private void initializePointList() {
pointsList = new ArrayList<Points>();
}
public List<Points> fromDB() {
TravelDB traveldb = new TravelDB(context);
traveldb.open();
Cursor cursor = traveldb.fetchAllGpsPoints(travelId);
loadPoints(cursor);
cursor.close();
traveldb.close();
return pointsList;
}
protected void loadPoints(Cursor cursor) {
initializePointList();
cursor.moveToFirst();
int gpsIndex = cursor.getColumnIndex(colGpsId);
int latitudeIndex = cursor.getColumnIndex(colGpsLatitude);
int longitudeIndex = cursor.getColumnIndex(colGpsLongitude);
int dateIndex = cursor.getColumnIndex(colGpsDate);
for (int progress=0; progress<cursor.getCount(); progress++) {
Points points = new Points();
points.setLatitude(cursor.getInt(latitudeIndex));
points.setLongitude(cursor.getInt(longitudeIndex));
points.setDataRilevamento(cursor.getLong(dateIndex));
points.setGpsId(cursor.getInt(gpsIndex));
pointsList.add(points);
cursor.moveToNext();
}
}
这里是我构建包含标记点的数组的地方,因为每个标记都存在一个或多个图像
private void buildPoints () {
List<Images> images = travel.getImages();
Log.i("DDV", "images:"+images.size());
// se esistono punti
if (!images.isEmpty()) {
length = images.size();
for (progress = 0 ; progress < length; progress++) {
currentImage = images.get(progress);
// verifico se una località con coordinate simili era già stata presa in esame
// in quel caso la raggruppo insieme alle altre
if ((oldImage != null) && (near(oldImage.getGeopoint(), currentImage.getGeopoint()))) {
overlayitem.addImage(currentImage);
if (currentImage.getAddress().length() == 0) {
if (oldImage.getAddress().length() > 0) {
currentImage.setAddress(oldImage.getAddress());
travel.addImages(currentImage);
}
}
}
// in questo caso vuol dire che le coordinate sono troppo differenti per unirle in una
// quindi salvo l'oggetto vecchio e ne instanzio uno nuovo
else if (oldImage != null) {
setTextAndSave(oldImage);
createOverlay(currentImage.getGeopoint());
oldImage = currentImage;
}
// in questo caso è la prima volta che instanzio una coordinata
else {
oldImage = currentImage;
// geocoding per determinare il nome della via dove è stato generato il contenuto
// se nel db non è presente
if (currentImage.getAddress().length() == 0)
currentImage = geoCode(currentImage);
// aggiungo il marker
createOverlay(currentImage.getGeopoint());
}
// faccio progredire la sbarra
onProgressUpdate((int)(progress*100/length));
}
setTextAndSave(oldImage);
}
}
这是我为 map 建立线的地方
private void buildRoute() {
points = travel.getPoints();
length = points.size();
long tmp = DateManipulation.getCurrentTimeMs();
Log.i("DDV", "START PARSIN POINTSL: " +tmp);
if (length > 1) {
Points currentPoint = points.get(0);
Points oldPoint=currentPoint;
for (int progress=0; progress<length; progress++) {
currentPoint = points.get(progress);
if (currentPoint.getGeoPoint() != oldPoint.getGeoPoint()) {
oldPoint = currentPoint;
polyLine.add(currentPoint.getGeoPoint());
setZoomAndCenter(currentPoint);
}
onProgressUpdate((int)(progress*100/length));
}
}
saveCenterPosition();
}
如果您还需要其他东西,请随意询问。
谢谢大家
编辑 - 这是方法 getGeoPoint
public GeoPoint getGeoPoint() {
GeoPoint geoPoint = new GeoPoint(latitude, longitude);
return geoPoint;
}
最佳答案
我建议您使用 DDMS 进行一些跟踪,它会显示您花费最多时间的地方并帮助您进行优化。
我怀疑,在处理了 GeoPoint 之后,您没有做足够的缓存。 “新 GeoPoint”构造函数非常昂贵,因此如果您对该实例化执行数百次操作,我建议您重新考虑如何缓存它。
我想看看 codePoint.getGeoPoint()
背后的逻辑
我看到您将原始纬度/经度存储在数据库中。这样进出就快了。同样,我认为是 GeoPoint 对象的创建花费了大量时间。遗憾的是,没有办法使 GeoPoint 可序列化并存储它。因此,一旦将其从数据库中拉出,您就无法实例化它。
做一个跟踪,让我们看看结果是什么。 :)
关于Android,从内部数据库加载缓慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9019905/