Android:LocationManager泄漏,即使调用了removeUpdates

时间:2018-01-26 06:37:41

标签: android memory-leaks

我已经实现了一个片段,用于获取设备的GPS位置。出于某种原因,我得到了内存泄漏 - 即使我取消注册侦听器(如所有关于LocationManager内存泄漏的帖子中所建议的)。我对Android仍然相对较新,所以它可能是完全愚蠢的。

public class GetLocationTask extends Fragment {

/**
 * Callback interface through which the fragment will report the
 * task's progress and results back to the Activity. Calling activity MUST implement this.
 */
public interface LocationCallbacks {
    void onLocationReceived(double latitude, double longitude);
}

/** The calling activity. */
private LocationCallbacks mCallbacks;

private LocationManager locationManager;
private LocationListener locationListener;

/** Create a new instance. */
public static GetLocationTask newInstance() {
    GetLocationTask f = new GetLocationTask();

    // Supply index input as an argument.
    Bundle args = new Bundle();
    f.setArguments(args);

    return f;
}

@Override
public void onAttach(Context activity) {
    super.onAttach(activity);
    if (activity instanceof LocationCallbacks) {
        mCallbacks = (LocationCallbacks) activity;
    } else {
        Log.w("GetLocationTask", "CALLING CLASS DOES NOT IMPLEMENT INTERFACE!");
    }
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setRetainInstance(true);

    locationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
    locationListener = new LocationListener() {
        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {

        }

        @Override
        public void onProviderEnabled(String provider) {

        }

        @Override
        public void onProviderDisabled(String provider) {

        }

        public void onLocationChanged(Location location) {
            if (location != null) {
                double longitude = location.getLongitude();
                double latitude = location.getLatitude();

                locationManager.removeUpdates(locationListener);

                mCallbacks.onLocationReceived(latitude, longitude);
                Log.i("result", longitude +  "   >> " + latitude);
            } else {
                Log.i("waiting", "warming up still");
            }
        }
    };


    try {
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 90, locationListener);
    } catch (SecurityException e) {
        Log.i("TODO", "TODO");
    }

}

@Override
public void onDestroy() {
    super.onDestroy();
    if (locationManager != null && locationListener != null) {
        locationManager.removeUpdates(locationListener);
    }
    locationListener = null;
    locationManager = null;
}

@Override
public void onDetach() {
    super.onDetach();
    mCallbacks = null;
}
}

1 个答案:

答案 0 :(得分:1)

您可以通过不让locationListener引用任何相关片段来防止内存泄漏。

您将LocationListener创建为一个匿名类,因此它引用了您的片段,并且还直接引用了mCallbacks,这是片段的属性。

将locationListener定义为一个单独的类,您只需在片段中实例化它,然后将回调接口作为构造函数参数传递给listener类,或者甚至更好的办法是在locationlistener上观察LiveData实例(显然使用片段的lifecycleOwner)。