2016-11-14 81 views
6

我正在使用play服务v9.8.0(没有位置服务权限),并且在对话框片段中使用MapView时仍然面临泄漏。我使用它就像在我的代码示例中,我用它来显示一个位置,我没有setMyLocationEnabled(因为我甚至没有这个设置的权限)。MapView泄漏活动(无位置服务)

有人在我的代码中看到问题吗?我在这里得到一个泄漏:MapView v2 keeping Context around。我做如下:

  • 创建一个对话框
  • MapView替换我的布局视图(因为我允许使用静态地图一样,所以我的默认视图是我的布局ImageView,这将是用MapView

更换然后它发生,我的片段泄漏MapView.mContext ...

码 - 对话片段

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.onDestroyGoogleMap.setMyLocationEnabled(false)将导致泄漏。这里有一个相关的thread可能有帮助。

+0

调用'setLocationEnabled'需要位置权限,我的应用程序没有它,所以我无法启用它,也没有禁用它...所以这对我来说现在是无法解决的... – prom85

0

我有同样的问题,并在我的堆参考树中发现错误来自库的lite模式部分。尽量不要使用lite模式并为mapview添加所有相应的生命周期。

+1

你能解释一下你的意思吗? ?在我的例子中,我已经添加了所有我认为的生命周期事件。或者我错过了什么? – prom85

+0

@ prom85 [精简模式文档](https://developers.google.com/maps/documentation/android-api/lite) 这是一个功能,只显示您指定的位置片段上的位图。检查你的片段xml是否有map:liteMode =“true” – sufeiz