Карты Google на Android ужасно медленные или я использую их неправильно? - PullRequest
3 голосов
/ 01 апреля 2011

Итак, я портирую приложение, созданное для iOS, пару месяцев назад на Android. Это приложение имеет базу данных из нескольких сотен (341) точек, которые могут быть показаны на карте. Когда я делал это на iOS, у меня не возникало проблем с добавлением этих точек на мою карту. Убедитесь, что пользователь уменьшил масштаб так, чтобы все точки, где они были видны одновременно, могли заметить некоторое замедление, но ничего существенного. На Android, с другой стороны, это мучительно медленно до точки замерзания. Это также медленнее на AVD, чем на телефоне (HTC Hero).

Я хотел бы отметить, что я новичок в Java, но у меня есть опыт работы с C / C ++ / OBJ-C. Я немного поэкспериментировал с моим кодом и использовал некоторые простые измерения производительности и пришел к некоторым неожиданным выводам по поводу моего кода.

Это моя функция в MapActivity для добавления наложений на мою карту. Я оставил там закомментированный код, который я объясню.

private void addOverlaysToMapFromManagedInterestPoints() {

       this.mapOverlays = myMap.getOverlays();

        GeoPoint point;
        OverlayItem overlayitem;



       for( managed_interest_point mip : managedObjectManager.interestPoints )
        {


            TypeOfPoint type = getEnumForTypeOfPoint(mip.ZTYPEOFPOINT);
            if(type!=null)
            {
                switch (type) {
                case kAnimalHospital:
                    point = new GeoPoint(degreesToMicrodegreesConversion(mip.ZLATITUDE),degreesToMicrodegreesConversion(mip.ZLONGITUDE));
                    overlayitem  = new OverlayItem(point, mip.ZTITLE, mip.ZSUBTITLE);                   
                    //this.animalHospitalOverlay.addOverlay(overlayitem);
                    AnnotationsOverlay testOverlay =  new AnnotationsOverlay(this.animalHospitalPin,this);
                    testOverlay.addOverlay(overlayitem);
                    Log.d("MainActivity","added animalHospital");
                    break;
                case kStore:
                    point = new GeoPoint(degreesToMicrodegreesConversion(mip.ZLATITUDE),degreesToMicrodegreesConversion(mip.ZLONGITUDE));
                    overlayitem = new OverlayItem(point, mip.ZTITLE, mip.ZSUBTITLE);                                     
                    //this.storesOverlay.addOverlay(overlayitem);   
                    AnnotationsOverlay testOverlay2 =  new AnnotationsOverlay(storePin,this);
                    testOverlay2.addOverlay(overlayitem);
                    this.mapOverlays.add(testOverlay2);
                    Log.d("MainActivity","added Store point");
                    break;
                case kVeterinary:                       
                    point = new GeoPoint(degreesToMicrodegreesConversion(mip.ZLATITUDE),degreesToMicrodegreesConversion(mip.ZLONGITUDE));
                     overlayitem = new OverlayItem(point, mip.ZTITLE, mip.ZSUBTITLE);                   
                     //this.storesOverlay.addOverlay(overlayitem);
                     AnnotationsOverlay testOverlay3 =  new AnnotationsOverlay(this.veterinaryPin,this);
                     testOverlay3.addOverlay(overlayitem);
                     this.mapOverlays.add(testOverlay3);
                     Log.d("MainActivity","added veterinary point");
                     break;
                default:
                    Log.d("MainActivity", "unknown enum");
                    break;
                }//end switch
            }//end if 
        }//end foreach

       //this.mapOverlays.add(this.storesOverlay);
       //this.mapOverlays.add(this.veterinariesOverlay);
       //this.mapOverlays.add(this.animalHospitalOverlay);  
       Log.d("MainActivity","end of foreach in add overlays to map ");


}

И это код для моего подкласса AnnotationsOverlay для ItemizedOverlay.

public class AnnotationsOverlay extends ItemizedOverlay {

private ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>();
Context mContext;



public AnnotationsOverlay(Drawable defaultMarker) {
    super(boundCenterBottom(defaultMarker));

}

public AnnotationsOverlay(Drawable defaultMarker,Context context)
{
    super(boundCenterBottom(defaultMarker));
    mContext=context;

}

@Override
protected OverlayItem createItem(int i) {


    return mOverlays.get(i);
}

@Override
public int size() {

    return mOverlays.size();
}

//show calloutAssesory view tapped för oss iPhöne människor
@Override
protected boolean onTap(int index) {
  OverlayItem item = mOverlays.get(index);
  AlertDialog.Builder dialog = new AlertDialog.Builder(mContext);
  dialog.setTitle(item.getTitle());
  dialog.setMessage(item.getSnippet());
  dialog.show();
  return true;
}

public void addOverlay(OverlayItem overlay)
{
    mOverlays.add(overlay);
    populate();
}

}

Моим первым инстинктом было то, что выделение AnnotationsOverlay внутри цикла было бы плохо, так как кажется, что он работает как некая коллекция, к которой вам следует добавить несколько элементов.

Это предположение оказалось неверным, поскольку каждый последующий вызов add () занимал все больше и больше времени. Я поместил это распределение внутри цикла, и теперь эта функция выполняется в приемлемое время. Все точки отображаются на карте, но это очень медленно (возможно, на 2 кадра в секунду). Я думаю, что это странно, что каждый вызов add также вызывает populate (); функция. Я попытался удалить это и написать публичный метод, который переносит заполнение, которое я вызываю только после добавления всех элементов, но это просто не ощущается. Написание общедоступных методов для обёртывания частных, как правило, не очень хорошая идея. Также это дает мне странное поведение, и все оверлеи получают одно и то же изображение, если я делаю это.

Так что же я делаю не так, или это просто факт, что Google Maps API на Android намного менее гибок, чем на iOS?

Ответы [ 2 ]

3 голосов
/ 01 апреля 2011

Я делаю некоторые успехи здесь, которые могут быть полезны для некоторых из вас, читающих этот вопрос. 1. Теперь я переместил свой метод populate из моего метода add и обернул его в открытый метод, чтобы я мог вызывать его только один раз после заполнения всего массива OverlayItems. Также я попытался запустить приложение без отладчика, то есть просто запустить приложение на телефоне, и тогда оно работает гладко. Это не единственный раз, когда я заметил, что отладчик замедляет работу в 10-20 раз или более. В прошлом у меня были подобные проблемы, когда работа в режиме отладки сильно замедляла некоторые операции.

Новый код выглядит так:

    private void addOverlaysToMapFromManagedInterestPoints() {

       this.mapOverlays = myMap.getOverlays();

        GeoPoint point;
        OverlayItem overlayitem;



       for( managed_interest_point mip : managedObjectManager.interestPoints )
        {

            if(mip==null)
            {
                Log.d("MainActivity","this should not happen!");
            }

            TypeOfPoint type = getEnumForTypeOfPoint(mip.ZTYPEOFPOINT);
            if(type!=null)
            {
                switch (type) {
                case kAnimalHospital:
                    point = new GeoPoint(degreesToMicrodegreesConversion(mip.ZLATITUDE),degreesToMicrodegreesConversion(mip.ZLONGITUDE));
                    overlayitem  = new OverlayItem(point, mip.ZTITLE, mip.ZSUBTITLE);                   
                    this.animalHospitalOverlay.addOverlay(overlayitem);
                    Log.d("MainActivity","added animalHospital");
                    break;
                case kStore:
                    point = new GeoPoint(degreesToMicrodegreesConversion(mip.ZLATITUDE),degreesToMicrodegreesConversion(mip.ZLONGITUDE));
                    overlayitem = new OverlayItem(point, mip.ZTITLE, mip.ZSUBTITLE);                                     
                    this.storesOverlay.addOverlay(overlayitem); 
                    Log.d("MainActivity","added Store point");
                    break;
                case kVeterinary:                       
                    point = new GeoPoint(degreesToMicrodegreesConversion(mip.ZLATITUDE),degreesToMicrodegreesConversion(mip.ZLONGITUDE));
                     overlayitem = new OverlayItem(point, mip.ZTITLE, mip.ZSUBTITLE);                   
                     this.veterinariesOverlay.addOverlay(overlayitem);
                     Log.d("MainActivity","added veterinary point");
                     break;
                default:
                    Log.d("MainActivity", "unknown enum");
                    break;
                }//end switch
            }//end if 
        }//end foreach

      this.storesOverlay.callToPopulate();
      this.veterinariesOverlay.callToPopulate();
      this.animalHospitalOverlay.callToPopulate();


       this.mapOverlays.add(this.storesOverlay);
       this.mapOverlays.add(this.veterinariesOverlay);
       this.mapOverlays.add(this.animalHospitalOverlay);    
       Log.d("MainActivity","end of foreach in add overlays to map ");


}



public class AnnotationsOverlay extends ItemizedOverlay {

private ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>();
Context mContext;



public AnnotationsOverlay(Drawable defaultMarker) {
    super(boundCenterBottom(defaultMarker));

}

public AnnotationsOverlay(Drawable defaultMarker,Context context)
{
    super(boundCenterBottom(defaultMarker));
    mContext=context;

}

@Override
protected OverlayItem createItem(int i) {


    return mOverlays.get(i);
}

@Override
public int size() {

    return mOverlays.size();
}

//show calloutAssesory view tapped för oss iPhöne människor
@Override
protected boolean onTap(int index) {
  OverlayItem item = mOverlays.get(index);
  AlertDialog.Builder dialog = new AlertDialog.Builder(mContext);
  dialog.setTitle(item.getTitle());
  dialog.setMessage(item.getSnippet());
  dialog.show();
  return true;
}

public void addOverlay(OverlayItem overlay)
{
    mOverlays.add(overlay);
    //populate();
}

public void callToPopulate()
{
    populate();
}



}
0 голосов
/ 28 января 2013

Добавление

mapOverlays.clear();

Сразу после

mapOverlays.add(itemizedOverlay);

Немного увеличил производительность моего приложения.

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