'Memory leak with Location update with fusedLocationProvider
Most of the common suggestions is, as it seems leaks are coming from context, use application context and detach location call from activity lifecycle. I did both previous thing and also later. But leak still existing. Here is my implementation with viewmodel,
public class LocationViewModel extends ViewModel {
private final MutableLiveData<Location> _locationLive = new MutableLiveData<>();
public LiveData<Location> locationLive = _locationLive;
private final static String TAG = "LocationViewModel";
private final FusedLocationProviderClient mFusedLocationClient;
private LocationRequest locationRequest;
private WeakReference<LocationCallback> locationCallback;
private static final long UPDATE_INTERVAL = 5000, FASTEST_INTERVAL = 3000;
public LocationViewModel() {
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(MyApp.getApplication());
prepareGpsAccess();
}
private void prepareGpsAccess() {
locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(UPDATE_INTERVAL); // 10 seconds
locationRequest.setFastestInterval(FASTEST_INTERVAL); // 5 seconds
locationCallback = new WeakReference<>(new LocationCallback() {
@Override
public void onLocationResult(@NonNull LocationResult locationResult) {
for (Location location : locationResult.getLocations()) {
_locationLive.postValue(location);
stopLocationUpdates();
}
}
});
}
public void stopLocationUpdates() {
if (mFusedLocationClient != null && locationCallback.get() != null) {
try {
final Task<Void> voidTask = mFusedLocationClient.removeLocationUpdates(locationCallback.get());
voidTask.addOnCompleteListener(task -> {
Log.e(TAG, "StopLocation addOnCompleteListener: " + task.isComplete());
if (task.isSuccessful()) {
Log.d(TAG, "StopLocation updates successful! ");
} else {
Log.d(TAG, "StopLocation updates unsuccessful! " + voidTask.toString());
}
});
voidTask.addOnSuccessListener(aVoid -> Log.e(TAG, "StopLocation addOnSuccessListener: "));
voidTask.addOnFailureListener(e -> Log.e(TAG, "StopLocation addOnFailureListener: " + e.toString()));
} catch (SecurityException exp) {
Log.d(TAG, "StopLocation Security exception while removeLocationUpdates");
}
}
}
public void getLocation() {
if (ActivityCompat.checkSelfPermission(MyApp.getApplication(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(MyApp.getApplication(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
mFusedLocationClient.requestLocationUpdates(locationRequest, locationCallback.get(), Looper.myLooper());
}
}
Here is the LeakCanary output,
1 APPLICATION LEAKS
References underlined with "~~~" are likely causes.
Learn more at https://squ.re/leaks.
549 bytes retained by leaking objects
Signature: 567aad2e1a38902d91202892cd70b65cb7df4f3
┬───
│ GC Root: Global variable in native code
│
├─ com.google.android.gms.location.zzam instance
│ Leaking: UNKNOWN
│ Retaining 1.5 kB in 31 objects
│ ↓ zzam.zza
│ ~~~
├─ com.google.android.gms.location.zzx instance
│ Leaking: UNKNOWN
│ Retaining 807 B in 23 objects
│ ↓ zzx.zzc
│ ~~~
├─ com.package.LocationViewModel$1 instance
│ Leaking: UNKNOWN
│ Retaining 561 B in 17 objects
│ Anonymous subclass of com.google.android.gms.location.LocationCallback
│ ↓ LocationViewModel$1.this$0
│ ~~~~~~
╰→ com.package.LocationViewModel instance
Leaking: YES (ObjectWatcher was watching this because com.package.location.LocationViewModel received
ViewModel#onCleared() callback)
Retaining 549 B in 16 objects
key = f23437cd-aafa-4153-866b-2b8961646172
watchDurationMillis = 14454
retainedDurationMillis = 9452
I have tried numerous thing, still this leak exist. Please share if you know another way to avoid this leak.
There is a relevant issue still open here, https://github.com/android/location-samples/issues/100
Solution 1:[1]
So basically, this issue was fixed by updating google, before I was using 16.xx. Finally I updated to 17.0.0 and this issue were gone.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | asish |
