首页 > 解决方案 > FusedLocationProviderClient 是否泄漏内存?

问题描述

在我的一项活动中,我使用 FusedLocationProviderClient 来获取不断的位置更新。我的代码基于这种方法:https ://developer.android.com/training/location/receive-location-updates

在我的 onCreate 中,我设置了提供程序和回调

// setup fused location provider
mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);

    // build location request
    mLocationRequest = new LocationRequest();
    mLocationRequest.setInterval(30000);
    mLocationRequest.setFastestInterval(10000);
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    mLocationRequest.setSmallestDisplacement(50);

    // Setup the callback function.
    mLocationCallback = new LocationCallback() {
        @Override
        public void onLocationResult(LocationResult locationResult) {
            if (locationResult == null) {
                return;
            }
            for (Location location : locationResult.getLocations()) {
                // Update UI with location data
                // ...

                mCurrentLocation = location;
            }
        }
    };

在 onResume

mFusedLocationProviderClient.requestLocationUpdates(mLocationRequest,
                                mLocationCallback,
                                Looper.myLooper());

在 onPause

mFusedLocationProviderClient.removeLocationUpdates(mLocationCallback);

然而由于某种原因,leak canary 仍然表明存在内存泄漏。泄漏金丝雀日志如下所示 在此处输入图像描述

浏览堆栈溢出,有些帖子似乎表明泄漏是由于 google play 服务造成的。但是那些帖子在谈论 fusedLocationApi,而我正在使用 fusedLocationProviderClient,所以我不确定它是否与我在这里使用的相同。有人可以为我确认吗?谢谢!

标签: androidmemory-leakslocationfusedlocationproviderclient

解决方案


我通过将 LocationCallback 的 SoftReference 传递给 FusedLocationProvider 来修复 LeakCanary 报告的泄漏。

public class LocationCallbackReference extends LocationCallback {

    private final SoftReference<LocationCallback> mLocationCallbackRef;

    public LocationCallbackReference(LocationCallback locationCallback) {
        mLocationCallbackRef = new SoftReference<>(locationCallback);
    }

    @Override
    public void onLocationResult(LocationResult locationResult) {
        super.onLocationResult(locationResult);
        if (mLocationCallbackRef.get() != null) {
            mLocationCallbackRef.get().onLocationResult(locationResult);
        }
    }

    @Override
    public void onLocationAvailability(LocationAvailability locationAvailability) {
        super.onLocationAvailability(locationAvailability);
        if (mLocationCallbackRef.get() != null) {
            mLocationCallbackRef.get().onLocationAvailability(locationAvailability);
        }
    }
}

我希望这会有所帮助。


推荐阅读