MapView v2, поддерживающий контекст

При использовании MapView из новейшего API карт Google, я получаю утечку памяти, потому что MapView удерживает мою активность.

Я использовал Leak Canary и получил эту трассировку


D/LeakCanary: * GC ROOT com.google.android.gms.location.internal.t.a

D/LeakCanary: * ссылки com.google.android.gms.location.internal.s.a

D/LeakCanary: * ссылки com.google.maps.api.android.lib6.d.v.c

D/LeakCanary: * ссылки com.google.maps.api.android.lib6.d.aj.b

D/LeakCanary: * ссылки com.google.maps.api.android.lib6.gmm6.c.p.a

D/LeakCanary: * ссылки com.google.maps.api.android.lib6.gmm6.c.y.mParent

D/LeakCanary: * ссылки android.widget.FrameLayout.mParent

D/LeakCanary: * ссылки com.google.android.gms.maps.MapView.mContext

D/LeakCanary: * утечка com.myapp.activities.main.AttractionDetailActivity instance


Кто-нибудь видел это раньше?

Ответ 1

Убедитесь, что вы вызываете googleMap.setMyLocationEnabled(true) в обратном вызове onMapReady().

Если вы находитесь, тогда вы должны позвонить googleMap.setMyLocationEnabled(false) в свой onDestroy.

Ответ 2

Это сработало для меня:

@Override
    public void onDestroy() {
        super.onDestroy();
        mMapView.onDestroy();
        if (mMap != null) {
            mMap.setMyLocationEnabled(false);
            mMap.clear();
        }
    }

Ответ 3

Просто, чтобы дать другой вариант, поскольку это решение не сработало для меня.

Я нашел этот действительно полезный поток, где он предлагает некоторые обходные пути, связанные с утечкой памяти в MapView:

https://github.com/googlesamples/android-play-location/issues/26

Для меня самые интересные вещи из этого потока (который работал у меня):

1) Обязательно отмените регистрацию обратных вызовов:

if (googleApiClient != null) {
        googleApiClient.unregisterConnectionCallbacks(this);
        googleApiClient.unregisterConnectionFailedListener(this);

        if (googleApiClient.isConnected()) {
                LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, this);
        }

        googleApiClient.disconnect();
        googleApiClient = null;
 }

2) Используйте WeakReference для 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);
    }

}

Надеюсь, что это поможет!