FusedLocationProviderClient是否会导致内存泄漏?

4
在我的一个活动中,我正在使用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仍然表明存在内存泄漏。下面是Leak Canary的日志记录:enter image description here 在Stack Overflow上浏览时,有一些帖子表明泄漏是由Google Play服务引起的。但是这些帖子涉及到fusedLocationApi,而我正在使用fusedLocationProviderClient,所以我不确定它是否与我正在使用的内容相同。能否有人为我确认一下?谢谢!
3个回答

4

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

我希望能够帮到您。

对我有用。如果有人想知道如何使用它:只需创建与上述类相同的类,并在正常创建myLocationCallback实例后,将LocationCallbackReference(myLocationCallback)传递给client.requestLocationUpdates(...)。 - Androidz
有趣的回答,但为什么弱引用不起作用呢?@Marcin - max

2

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

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

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
    }
}

}


1
谷歌最近在其最新的play-services-location:20.0.0版本中解决了这个内存泄漏问题。发行说明
要了解更多关于这个内存泄漏历史的信息,请查看thisthis

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