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);
И все же по какой-то причине утечка канарейки все еще указывает на утечку памяти. Утечка канарейка, показанная ниже
Просматривая вокруг переполнения стека, есть сообщения, которые, кажется, предполагают, что утечка связана с сервисом Google Play. Но эти посты говорили о fusedLocationApi, в то время как я использую fusedLocationProviderClient, поэтому я не уверен, что это то же самое, что я использую здесь. Кто-нибудь может подтвердить для меня? Спасибо!
3 ответа
Я исправил утечки, о которых сообщает LeakCanary, передав SoftReference LocationCallback в FusedLocationProvider.
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);
}
}
}
Надеюсь, это поможет.
Для меня я использовал 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
}
}
}
Google недавно решил эту проблему с утечкой памяти в своем последнем выпуске play-services-location:20.0.0. Примечание к выпуску .
Чтобы узнать больше об истории этой утечки памяти, проверьте это и это .