Android,从内部数据库缓慢加载

时间:2012-01-26 14:49:57

标签: android performance maps

我的应用程序必须从android的内部sqlite数据库加载一些“点”,然后将这些点转换为地图上的行,然后从数据库中加载其他“点”,这些点将成为地图上的标记。 / p>

问题是上述加载过程非常慢。这个过程可能需要几秒钟,在最坏的情况下也需要几分钟。

数据库中的点来自服务,它跟踪您的位置。我已经在这个服务中实现了一些避免点数过剩的方法,比如时间控制(如果两个后续点已经太接近,第二个没有保存),位置控制(如果两个后续点具有相同的坐标,最后一次不会被保存)和距离检查(如果两个后续点距离太近,则不会保存最后一个)。

在加载过程中,这些点上可能会出现其他计算,但在最佳情况下也会出现缓慢,只有从数据库中读取才会出现。

这是我创建包含地图上绘制线点的数组的地方。

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

这是我为地图构建线的地方

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

1 个答案:

答案 0 :(得分:1)

我建议您使用DDMS进行一些跟踪,它会告诉您花费最多时间的地方并帮助您进行优化。

我怀疑,在处理GeoPoint之后,你没有做足够的缓存。 “新的GeoPoint”构造函数非常昂贵,所以如果您正在进行该实例化的几百个操作,我建议您重新考虑如何缓存它。

我想看看codePoint.getGeoPoint()

背后的逻辑

我看到你将原始lat / lng存储在数据库中。进出的速度很快。同样,我认为这是你的GeoPoint对象的创建需要花费很多时间。可悲的是,没有办法让GeoPoint可序列化并存储它。因此,只要将其从数据库中取出,就会被卡住实例化。

做一个跟踪,让我们看看结果是什么。 :)