I'm using the play services v9.8.0 (without location service permissions) and am still facing a leak when I use a MapView
in a dialog fragment. I'm using it like in my code example and I use it to display a location only and I DON'T have setMyLocationEnabled
(as I don't even have the permissions for this setting).
Does anyone see a problem in my code? I'm getting a leak like the one here: MapView v2 keeping Context around. I do following:
MapView
(because I allow to use static maps as well, so my default view is a ImageView
in my layout, that will be replaced with a MapView
)Then it happens that my fragments leaks MapView.mContext
...
Code - Dialog Fragment
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;
}
}
There are some issues reported about leaks with MapView. You may try calling googleMap.setMyLocationEnabled(false);
in onDestroy
to prevent the leak from happening. Failure to call either MapView.onDestroy
or GoogleMap.setMyLocationEnabled(false)
will cause a leak. Here's a related thread which might help.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With