3

在我的一项活动中,我使用 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,所以我不确定它是否与我在这里使用的相同。有人可以为我确认吗?谢谢!

4

2 回答 2

3

我通过将 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);
        }
    }
}

我希望这会有所帮助。

于 2018-08-16T21:01:02.393 回答
2

对我来说,我使用 LocationCallback 作为内部匿名对象(因为我必须更新/访问封闭类数据)& FusedLocationProviderClient导致内存泄漏。

然后我将内部类重构为静态(非内部)类并通过传递给静态 LocationCallback 对象的实时数据更新封闭类数据。

import android.app.Activity
import androidx.lifecycle.MutableLiveData
import com.google.android.gms.location.*


class LocationUtility constructor(private val activity: Activity) {


private var mLocationRequest: LocationRequest? = null
private var fusedLocationProviderClient: FusedLocationProviderClient? = null

var currentLocation = MutableLiveData<Pair<Double?, Double?>>()

private var myLocationCallback: MyLocationCallback? = null


init {
    fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(activity)
    myLocationCallback = MyLocationCallback(currentLocation)
}



// Location call back
private class MyLocationCallback(val liveData: MutableLiveData<Pair<Double?, Double?>>) :
    LocationCallback() {

    override fun onLocationResult(locationResult: LocationResult?) {
        super.onLocationResult(locationResult)

        val latitude = locationResult?.locations?.get(0)?.latitude
        val longitude = locationResult?.locations?.get(0)?.longitude

        val locationInfo = Pair(latitude, longitude)
        liveData.value = locationInfo
    }
}

}

于 2020-07-26T20:54:16.790 回答