MapView v2保留上下文环境

11

在使用最新的Google Maps API的MapView时,我遇到了内存泄漏问题,因为MapView一直持有我的Activity。

我使用了Leak Canary并获得了以下跟踪信息:


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: * 泄漏了com.myapp.activities.main.AttractionDetailActivity实例


有人以前见过这种情况吗?


1
已知问题。如果有足够多的人给它点星,或许它会在2018年之前得到修复:https://code.google.com/p/gmaps-api-issues/issues/detail?id=8111 - Kevin Krumwiede
3个回答

20

检查你是否在 onMapReady() 回调中调用了 googleMap.setMyLocationEnabled(true)

如果是,则应该在 onDestroy 中调用 googleMap.setMyLocationEnabled(false)


实际上这个可行了... 但我认为这是一个应该被修复的错误,不过还是谢谢! - Marcel
4
即使采用了这种解决方法,我仍然看到泄漏问题出现。 - NasaGeek
@NasaGeek 猜想可能已经晚了,但可以确认泄漏是否与此相同或其他。Google Maps SDK 有许多泄漏,我猜最新版本的 Google Play 服务已经修复了其中大部分。 - Chaits

9
这对我有效:
(以下省略解释)
@Override
    public void onDestroy() {
        super.onDestroy();
        mMapView.onDestroy();
        if (mMap != null) {
            mMap.setMyLocationEnabled(false);
            mMap.clear();
        }
    }

1

仅提供另一种选项,因为这个解决方案对我无效。

我发现这个非常有用的帖子,其中提出了一些与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);
    }

}

希望它有所帮助!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接