Android, медленная загрузка из внутренней базы данных - PullRequest
2 голосов
/ 26 января 2012

Мое приложение должно загружать некоторые «точки» из внутренней базы данных sqlite для Android, и оно преобразует эти точки в линии на карте, затем из базы данных я загружаю другие «точки», которые становятся маркерами на карте.

Проблема в том, что процесс загрузки, описанный выше, очень медленный. Этот процесс может занять много секунд, а в худшем случае - и минуты.

Точки в базе данных поступают от службы, которая отслеживает вашу позицию. В этом сервисе я реализовал несколько методов, позволяющих избежать избытка точек, например, контроль времени (если две последующие точки были взяты слишком близко по времени, вторая не сохранена), контроль положения (если две последующие точки имеют одинаковые координаты последняя не будет сохранена) и проверка расстояния (если две последующие точки расположены слишком близко, последняя не будет сохранена).

Другие вычисления могут происходить в этих точках во время загрузки, но медлительность также присутствует в лучшем случае, когда это только чтение из базы данных.

Здесь я создаю массив, содержащий точки для рисования линий на карте.

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

Если вам нужно что-то еще, спросите свободно.

Спасибо всем.

EDIT - вот метод getGeoPoint

public GeoPoint getGeoPoint() {
    GeoPoint geoPoint = new GeoPoint(latitude, longitude);
    return geoPoint;
}

1 Ответ

1 голос
/ 26 января 2012

Я бы порекомендовал вам провести трассировку с помощью DDMS, он покажет вам, на что вы тратите больше всего времени, и поможет оптимизировать.

Я подозреваю, что после работы с GeoPoint вы недостаточно эффективно кешируете. «Новый GeoPoint» конструктор очень дорогой, поэтому, если вы выполняете несколько сотен операций этого экземпляра, я рекомендую переосмыслить, как вы кешируете это.

Я бы хотел увидеть логику codePoint.getGeoPoint()

Я вижу, что вы храните raw lat / lng в базе данных. Это будет быстро входить и выходить. Опять же, я предполагаю, что создание вашего объекта GeoPoint занимает много времени. К сожалению, нет способа сделать сериализованный GeoPoint и сохранить его. Так что вы застряли в его создании, как только вы извлечете его из базы данных.

Сделайте трассировку, давайте посмотрим, каков результат этого. :)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...