我已经实现了在用户点击协议按钮时获取用户的当前位置的功能。我已经在活动中实现了 LocationListener ,并且在 onStop 和 onDestroyed 上都未注册侦听器。但是根据 LeakCanary ,内存泄漏仍然存在。
这是我的代码的简短说明。
public class UserProfileEditActivity extends BaseActivity implements DatePickerDialog.OnDateSetListener, LocationListener, LocationResult {
LocationManager locationManager;
LocationHelper myLocation;
LocationResult locationResult;
public void getCurrentUserLocation() {
myLocation.getLocation(this);
}
@Override
protected void onStart() {
super.onStart();
locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
myLocation = new LocationHelper(locationManager, this);
}
@Override
protected void onPause() {
locationManager.removeUpdates(this);
super.onPause();
}
@Override
protected void onStop() {
reset();
super.onStop();
}
@Override
protected void onDestroy() {
reset();
super.onDestroy();
}
//implementation of LocationResult
@Override
public void gotLocation(Location location) {
//Got the location!
getCurrentUserHomeTown(location);
if (location != null)
showLog("Location lat :" + location.getLatitude() + " long :" + location.getLongitude());
}
private void reset() {
if (confirmationDialog != null)
confirmationDialog.dismiss();
if (myLocation != null) {
myLocation.stopLocationListeners();
locationManager.removeUpdates(this);
locationResult = null;
locationManager = null;
myLocation = null;
}
}
@Override
public void onLocationChanged(Location location) {
locationResult.gotLocation(location);
locationManager.removeUpdates(this);
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
这就是我触发收集位置的方式。
public void getCurrentUserLocation() {
myLocation.getLocation(this);
}
这是 LocationHelper.class
public class LocationHelper {
private LocationResult locationResult;
private LocationManager locationManager;
private boolean gps_enabled = false;
private boolean network_enabled = false;
// private Timer timer;
private LocationListener locationListener;
public LocationHelper(LocationManager locationManager, LocationListener locationListener) {
this.locationManager = locationManager;
this.locationListener = locationListener;
}
@SuppressLint("MissingPermission")
public boolean getLocation(LocationResult result) {
//I use LocationResult callback class to pass location value from MyLocation to user code.
locationResult = result;
//exceptions will be thrown if provider is not permitted.
try {
gps_enabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
network_enabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
} catch (Exception ignored) {
}
//don't start listeners if no provider is enabled
if (!gps_enabled && !network_enabled)
return false;
if (gps_enabled)
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10 * 1000, (float) 10.0, locationListener);
if (network_enabled)
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 10 * 1000, (float) 10.0, locationListener);
getLastLocation();
// timer.schedule(new GetLastLocation(locationManager, locationListenerGps, locationListenerNetwork, gps_enabled, network_enabled, locationResult), 40000);
return true;
}
@SuppressLint("MissingPermission")
public void getLastLocation() {
locationManager.removeUpdates(locationListener);
Location net_loc = null, gps_loc = null;
if (gps_enabled)
gps_loc = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (network_enabled)
net_loc = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
//if there are both values use the latest one
if (gps_loc != null && net_loc != null) {
if (gps_loc.getTime() > net_loc.getTime())
locationResult.gotLocation(gps_loc);
else
locationResult.gotLocation(net_loc);
return;
}
if (gps_loc != null) {
locationResult.gotLocation(gps_loc);
return;
}
if (net_loc != null) {
locationResult.gotLocation(net_loc);
return;
}
locationResult.gotLocation(null);
}
public void stopLocationListeners() {
locationManager.removeUpdates(locationListener);
// if (timer != null) {
// timer.cancel();
// timer = null;
// }
locationListener = null;
locationResult = null;
locationManager = null;
}
}
但是 LeakCanary 始终通过 LocationManager 和 LocationListener指示存在内存泄漏 。请帮助我找出答案。