2011-04-01 1 views
3

그래서 iOS 용으로 만든 앱을 Android로 두 달 전에 포팅했습니다. 이 응용 프로그램은지도에 표시 할 수있는 몇백 (341) 포인트의 데이터베이스를 가지고 있습니다. iOS에서이 작업을 수행 할 때지도에이 점을 추가 할 때 아무런 성능상의 문제가 발생하지 않았습니다. Shure는 사용자가 축소하여 모든 점을 한 번에 볼 수있는 곳에서 약간의 속도 저하를 볼 수 있지만 별다른 것을 알지 못하도록합니다. 반면에 안드로이드에서는 이것이 얼버무 리기 때문에 얼어 붙을 정도로 느리다. 또한 AVD는 휴대 전화 (HTC Hero)보다 느립니다.Android의 Google지도가 너무 느리거나 잘못된 방법으로 사용하고 있습니까?

나는 자바에 대한 새로운 커맨더이지만 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 "); 


} 

그리고 이것은 ItemizedOverlay에 대한 AnnotationsOverlay 내 하위 클래스의 코드입니다.

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 fps 가능할 수도 있음)입니다. 추가하는 각 호출도 populate()를 호출하는 것이 이상하다고 생각합니다. 기능. 나는 그것을 제거하고 모든 항목을 추가 한 후에 만 ​​호출하는 채우기를 공용 메서드로 작성하려고 시도했지만 그저 엄밀함을 느끼지 못합니다. 비공개의 메소드를 랩하기위한 public 메소드의 작성은 일반적으로 좋지 않습니다. 또한이 작업을 수행하면 이상한 동작이 발생하고 모든 오버레이가 동일한 이미지를 얻습니다.

그래서 내가 뭘 잘못하고있는거야, 아니면 안드로이드의 Google Maps API가 iOS보다 훨씬 덜 유연하다는 사실인가?

답변

3

나는이 질문을 읽는 사람들에게 도움이 될만한 진전을 보이고 있습니다. 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

멋진 찾기 ...'addOverlay()'에서'populate()'를 움직이는 것과 디버거가 단절된 상태에서 훨씬 빠르게 실행되는 방법 모두! Stackoverflow에 관한 다른 관련 질문/답변 6-7을 읽었으며이 제안을 처음 보았습니다! –

+0

내 성능 문제도 에뮬레이터와 관련이있는 것으로 보입니다. 앱이 휴대 전화에서 부드럽게 실행됩니다. – Sand

0

내 응용 프로그램까지 아주 약간의 성능을 질주 직선

mapOverlays.add(itemizedOverlay); 

mapOverlays.clear(); 

추가.

관련 문제