2016-11-14 5 views
6

Я использую службы воспроизведения v9.8.0 (без разрешений на предоставление услуг определения местоположения), и я все еще сталкиваюсь с утечкой, когда использую MapView в фрагменте диалога. Я использую его, как в моем примере кода, и использую его для отображения только местоположения, и у меня нет setMyLocationEnabled (так как у меня даже нет разрешений для этого параметра).Активность активности MapView (без службы определения местоположения)

Кто-нибудь видит проблему в моем коде? Я получаю утечку, как здесь: MapView v2 keeping Context around. Я следующее:

  • создать диалоговые
  • заменить вид на моем макете с MapView (потому что позволяют использовать статические карты, так что мое мнение по умолчанию в моем макете ImageView, что будет заменен MapView)

Тогда случается, что мои фрагменты просачивается MapView.mContext ...

код - Dialog Фрагмент

public class DialogMediaDetails extends DialogFragment 
{ 
    private GoogleMap mGoogleMap = null; 
    private MapView mMapView = null; 

    @Override 
    public final Dialog onCreateDialog(Bundle savedInstanceState) 
    { 
     Dialog dlg = ...; // create dialog 
     View view = ...; // get view from dialog 
     Location location = ...; // defined location 
     initGoogleMap(); 
     return dlg; 
    } 

    private void initGoogleMap(Location location) 
    { 
     mMapView = new MapView(getActivity()); 
     MapsInitializer.initialize(getActivity()); 
     // Updates the location and zoom of the MapView 
     mMapView.onCreate(null); 
     mMapView.getMapAsync(new OnMapReadyCallback() 
     { 
      @Override 
      public void onMapReady(GoogleMap googleMap) 
      { 
       LatLng coordinates = new LatLng(location.getLatitude(), location.getLongitude()); 
       googleMap.addMarker(new MarkerOptions().position(coordinates)); 
       googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(coordinates, 15)); 
       mGoogleMap = googleMap; 
       mMapView.onResume(); 
      } 
     }); 
     mMapView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() 
     { 
      @Override 
      public void onGlobalLayout() 
      { 
       mMapView.getViewTreeObserver().removeOnGlobalLayoutListener(this); 

       // MapView is scrollable, so we disable dragging 
       CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams(); 
       AppBarLayout.Behavior behavior = (AppBarLayout.Behavior) params.getBehavior(); 
       behavior.setDragCallback(new AppBarLayout.Behavior.DragCallback() { 
        @Override 
        public boolean canDrag(AppBarLayout appBarLayout) { 
         return false; 
        } 
       }); 
      } 
     }); 

     replaceHeader(mMapView); 
    } 

    private void replaceHeader(View view) 
    { 
     ViewGroup parent = (ViewGroup) pbHeader.getParent(); 
     int index = parent.indexOfChild(pbHeader); 
     ViewGroup.LayoutParams lp = pbHeader.getLayoutParams(); 
     parent.removeView(pbHeader); 
     parent.addView(view, index, lp); 
    } 

    // ---------------------------------------- 
    // forward all lifecycle events to MapView 
    // ---------------------------------------- 

    @Override 
    public void onResume() { 
     super.onResume(); 
     if (mMapView != null) 
      mMapView.onResume(); 
    } 

    @Override 
    public void onSaveInstanceState(Bundle outState) { 
     super.onSaveInstanceState(outState); 
     if (mMapView != null) 
      mMapView.onSaveInstanceState(outState); 
    } 

    @Override 
    public void onPause() { 
     super.onPause(); 
     if (mMapView != null) 
      mMapView.onPause(); 
    } 

    @Override 
    public void onLowMemory() { 
     super.onLowMemory(); 
     if (mMapView != null) 
      mMapView.onLowMemory(); 
    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
     if (mMapView != null) 
      mMapView.onDestroy(); 
     mMapView = null; 
    } 
} 
+0

Вы пытались использовать LeakCanary, чтобы определить, где началась утечка? – jakubbialkowski

+0

Да. Как и в ссылке, я получаю цепочку утечки, например «... mParent ссылки FrameLayout.mParent ссылки MapView.mContext" ... – prom85

+0

Вы узнали? – Laurent

ответ

1

Есть около issues сообщили об утечках с MapView. Вы можете попросить позвонить googleMap.setMyLocationEnabled(false); в onDestroy, чтобы предотвратить утечку. Невозможность вызвать либо MapView.onDestroy, либо GoogleMap.setMyLocationEnabled(false) вызовет утечку. Вот связанный thread, который может помочь.

+0

Вызов 'setLocationEnabled' нуждается в разрешении на местоположение, и у моего приложения нет его, поэтому я не могу его включить или отключить ... так что теперь это не решение для меня ... – prom85

0

У меня была такая же проблема, и я понял в дереве ссылок кучи, что ошибка исходит из части режима Lite в библиотеке. Не используйте режим Lite и добавляйте все соответствующие жизненные циклы для mapview.

+1

Можете ли вы объяснить, что вы имеете в виду при использовании режима Lite ? В моем примере я добавляю все жизненные циклы, которые я думаю. Или я чего-то не хватает? – prom85

+0

@ prom85 [Lite mode doc] (https://developers.google.com/maps/documentation/android-api/lite) Это функция, которая отображает только растровое изображение вашего фрагмента указанного вами местоположения. Проверьте свой фрагмент xml, если он имеет карту: liteMode = "true" – sufeiz

Смежные вопросы