When using the MapView from the latest google maps API, I am getting a memory leak because MapView is holding onto my activity.
I used Leak Canary and have this trace
D/LeakCanary﹕ * GC ROOT com.google.android.gms.location.internal.t.a
D/LeakCanary﹕ * references com.google.android.gms.location.internal.s.a
D/LeakCanary﹕ * references com.google.maps.api.android.lib6.d.v.c
D/LeakCanary﹕ * references com.google.maps.api.android.lib6.d.aj.b
D/LeakCanary﹕ * references com.google.maps.api.android.lib6.gmm6.c.p.a
D/LeakCanary﹕ * references com.google.maps.api.android.lib6.gmm6.c.y.mParent
D/LeakCanary﹕ * references android.widget.FrameLayout.mParent
D/LeakCanary﹕ * references com.google.android.gms.maps.MapView.mContext
D/LeakCanary﹕ * leaks com.myapp.activities.main.AttractionDetailActivity instance
Has anyone seen this before?
Check if you are calling googleMap.setMyLocationEnabled(true)
in your onMapReady() callback.
If you are then you should call googleMap.setMyLocationEnabled(false)
in your onDestroy.
This worked for me:
@Override
public void onDestroy() {
super.onDestroy();
mMapView.onDestroy();
if (mMap != null) {
mMap.setMyLocationEnabled(false);
mMap.clear();
}
}
Just to give another option as this solution didn't work for me.
I found this really useful thread where it propose some workarounds related to the memory leak in MapView:
https://github.com/googlesamples/android-play-location/issues/26
For me, the most interesting things from this thread (that worked for me) is:
1) Make sure to unregister your callbacks:
if (googleApiClient != null) {
googleApiClient.unregisterConnectionCallbacks(this);
googleApiClient.unregisterConnectionFailedListener(this);
if (googleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, this);
}
googleApiClient.disconnect();
googleApiClient = null;
}
2) Use a WeakReference for LocationListener
public class WeakLocationListener implements LocationListener {
private final WeakReference<LocationListener> locationListenerRef;
public WeakLocationListener(@NonNull LocationListener locationListener) {
locationListenerRef = new WeakReference<>(locationListener);
}
@Override
public void onLocationChanged(android.location.Location location) {
if (locationListenerRef.get() == null) {
return;
}
locationListenerRef.get().onLocationChanged(location);
}
}
Hope it helps!