位置监听器和内存泄漏问题

4
根据寻找用户位置的示例应用,监听活动中的位置变化是个好主意。
class MyActivity extends Activity implements LocationListener {
    @Inject
    private LocationManager locationManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
    }

    @Override
    public void onLocationChanged(Location location) {
        // do something with location
    }

    // ...
}

不过,我对此并不确定。当配置更改时,我的活动将被销毁和重建,下一次注册自己作为侦听器。旧Activity的引用保存在LocationManager中,对吗?

如果我将LocationListener提取到单独的对象中,仍然存在如何通知当前活动有新位置(不一定是请求活动相同)的问题。

是否有任何常见模式可以解决这个问题?


https://code.google.com/p/android/issues/detail?id=15170 - ecle
4个回答

5
在这个例子中,你还有另一个问题:你的GPS监听器将会一直工作并耗费电池电量。
更好的做法是:
1)在Activity的onStart()中注册LocationListener 2)在Activity的onStop()中移除LocationListener 这将解决这两个问题。
如果你需要让你的应用在后台跟踪用户位置(例如GPS追踪器),请使用Servicehttp://developer.android.com/reference/android/app/Service.html)。

2
这与使用 onPause()onResume() 有什么不同吗? - zundi

3

使用所有这些建议后,我遇到了内存泄漏问题。通过在不再需要Listener的点上,将此方法应用于onDestroy和onStop,我让它们停止了。我还将其添加到onPause中,但您需要决定是否最适合您的应用程序。

private void stopLocationListener() {
    if (locationManager !=null) locationManager.removeUpdates(locationListener);
    if (locationManager !=null) locationManager =null;
    if (locationListener !=null) locationListener =null;
}

泄漏仍然存在,但根据LeakCanary的显示已经变得更小了。 - Penzzz

1
你可以创建一个独立的类来实现相同的功能,然后将LocationListenerFinder.onLocationChanged接口实现到你的活动中。
现在你不会遇到泄漏问题了。
public class LocationListenerFinder implements LocationListener {
    onLocationChanged onLocationChanged;

    public LocationListenerFinder(Context context) {
        onLocationChanged = (LocationListenerFinder.onLocationChanged) context;
    }
    @Override
    public void onLocationChanged(Location location) {
        onLocationChanged.onLocationChanged(location);
        onLocationChanged = null;
    }

    public interface onLocationChanged {
        void onLocationChanged(Location location);
    }
}

在我的情况下,活动是这样的...您可以参考相同的内容,并根据自己的需求进行转换。
public class ActivityMapNearByPlace extends FragmentActivity implements OnMapReadyCallback,
    GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener, LocationListenerFinder.onLocationChanged {

private GoogleMap mMap;
ArrayList<LatLng> listMarkerPoints;
GoogleApiClient mGoogleApiClient;
Location mLastLocation;
Marker mCurrLocationMarker;
LocationRequest mLocationRequest;
private boolean locationPermission;
private ArrayList<NearByPlaces> listNearByFacility;
private int facilityPosition, locationPosition;
private ImageView ivBack, ivMyLocation;
private TextView tvPlaceOriginName, tvPlaceDestinationName, tvPlaceKmDistance, tvPlaceTime;
private TableRow trPlaceTimeKm;
private Marker currentSelectedMarker;
private Map<Integer, Map<String, Object>> mapDistancePathData;
private Polyline polyline;
private boolean flagCalculatingPath = false;
private FetchUrl fetchUrl;
private SupportMapFragment mapFragment;
private LocationListenerFinder locationListenerFinder;
//private WeakLocationListener locationListener;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_map_near_by_place);
    initView();
    initListener();

    if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        checkLocationPermission();
    } else {
        locationPermission = true;
    }
    // Initializing
    listMarkerPoints = new ArrayList<>();
    getBundleData();
    listNearByFacility.get(0).getNearBy();
    LatLng origin = new LatLng(Double.valueOf(listNearByFacility.get(0).getGeoLocLat()), Double.valueOf(listNearByFacility.get(0).getGeoLocLong()));
    listMarkerPoints.add(origin);
    // Obtain the SupportMapFragment and get notified when the map is ready to be used.
    mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);
}

@Override
protected void onRestart() {
    super.onRestart();
    //if (mGoogleApiClient != null) mGoogleApiClient.connect();
}

@Override
protected void onStop() {
    super.onStop();
    //if (mGoogleApiClient != null) mGoogleApiClient.disconnect();
}

@Override
protected void onDestroy() {
    super.onDestroy();
    if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
        LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, locationListenerFinder);
        mGoogleApiClient.disconnect();
        mGoogleApiClient.unregisterConnectionCallbacks(this);
        mGoogleApiClient.unregisterConnectionFailedListener(this);
        //  locationListener.clearData();
        locationListenerFinder = null;
    }
    mGoogleApiClient = null;
    fetchUrl.cancel(true);
    if (mMap != null) mMap.setMyLocationEnabled(false);
    //if (mapFragment != null) mapFragment.onDestroy();
}

@Override
public void onBackPressed() {
    finish();
}

private void initListener() {
    ivBack.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            onBackPressed();
        }
    });
    ivMyLocation.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if (mCurrLocationMarker.getTag() != null && !flagCalculatingPath) {
                locationPosition = (int) mCurrLocationMarker.getTag();
                if (mapDistancePathData.get(locationPosition) != null) {
                    if (polyline != null) {
                        polyline.remove();
                    }
                    Map<String, Object> hashMapDistancePathInfo = mapDistancePathData.get(locationPosition);
                    setPathInfo((String) hashMapDistancePathInfo.get("duration"), (String) hashMapDistancePathInfo.get("distance"), (PolylineOptions) hashMapDistancePathInfo.get("polyLineOptions"), "Current Location");
                    trPlaceTimeKm.setVisibility(View.VISIBLE);
                } else {
                    Locations locations = new Locations();
                    locations.setName("Current Location");
                    locations.setLatitude(String.valueOf(mLastLocation.getLatitude()));
                    locations.setLongitude(String.valueOf(mLastLocation.getLongitude()));
                    findDistanceAndMarkDirection(locations);
                }
            }
            //mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
            //mMap.animateCamera(CameraUpdateFactory.zoomTo(11));
        }
    });
}

private void initView() {
    ivBack = (ImageView) findViewById(R.id.iv_back_btn);
    ivMyLocation = (ImageView) findViewById(R.id.iv_my_location);

    tvPlaceOriginName = (TextView) findViewById(R.id.tv_near_by_place_origin);
    tvPlaceDestinationName = (TextView) findViewById(R.id.tv_near_by_place_destination);
    tvPlaceKmDistance = (TextView) findViewById(R.id.tv_near_by_place_km);
    tvPlaceTime = (TextView) findViewById(R.id.tv_near_by_place_time);
    trPlaceTimeKm = (TableRow) findViewById(R.id.tr_near_by_place_km_time);

}

private void getBundleData() {
    listNearByFacility = (ArrayList<NearByPlaces>) getIntent().getBundleExtra("nearByLocationBundle").getSerializable("nearByLocationData");
    facilityPosition = getIntent().getIntExtra("facilityPosition", 0);
    locationPosition = getIntent().getIntExtra("locationPosition", 0);
}

/**
 * Manipulates the map once available.
 * This callback is triggered when the map is ready to be used.
 * This is where we can add markers or lines, add listeners or move the camera. In this case,
 * we just add a marker near Sydney, Australia.
 * If Google Play services is not installed on the device, the user will be prompted to install
 * it inside the SupportMapFragment. This method will only be triggered once the user has
 * installed Google Play services and returned to the app.
 */
@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;

    //Initialize Google Play Services
    if (locationPermission) {
        buildGoogleApiClient();
        checkLocationStatus();
        //mMap.setMyLocationEnabled(true);
        loadMap();
    }
    mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
        @Override
        public boolean onMarkerClick(Marker marker) {
            if (marker.getTag() != null && !flagCalculatingPath) {
                locationPosition = (int) marker.getTag();
                if (mapDistancePathData.get(locationPosition) != null) {
                    if (polyline != null) {
                        polyline.remove();
                    }
                    Map<String, Object> hashMapDistancePathInfo = mapDistancePathData.get(locationPosition);
                    setPathInfo((String) hashMapDistancePathInfo.get("duration"), (String) hashMapDistancePathInfo.get("distance"), (PolylineOptions) hashMapDistancePathInfo.get("polyLineOptions"), listNearByFacility.get(0).getNearBy().get(facilityPosition).getLocations().get(locationPosition).getName());
                    trPlaceTimeKm.setVisibility(View.VISIBLE);
                } else {
                    findDistanceAndMarkDirection(listNearByFacility.get(0).getNearBy().get(facilityPosition).getLocations().get(locationPosition));
                }
            }
            return false;
        }
    });

    mMap.getUiSettings().setMyLocationButtonEnabled(false);
    mMap.getUiSettings().setRotateGesturesEnabled(false);
}

private void loadMap() {
    NearByPlaces originLocation = listNearByFacility.get(0);

    if (listMarkerPoints.size() > 1) {
        mMap.clear();
        listMarkerPoints.remove(1);
    }

    // Adding new item to the ArrayList
    NearBy nearBy = listNearByFacility.get(0).getNearBy().get(facilityPosition);
    tvPlaceOriginName.setText(originLocation.getProjectName());
    //tvPlaceDestinationName.setText(nearBy.getLocations().get(locationPosition).getName());
    if (mapDistancePathData == null) {
        mapDistancePathData = new HashMap<>();
    }
    // .get(locationPosition);
    // LatLng destination = new LatLng(Double.valueOf(location.getLatitude()), Double.valueOf(location.getLongitude()));
    //listMarkerPoints.add(destination);

    MarkerOptions options = new MarkerOptions();
    options.position(listMarkerPoints.get(0));
    options.icon(BitmapDescriptorFactory.fromBitmap(getBitmapMarker(originLocation.getProjectName(), R.drawable.ic_marker_red)));
    //options.title(originLocation.getProjectName());
    mMap.addMarker(options).showInfoWindow();
    for (int position = 0; position < nearBy.getLocations().size(); position++) {
        Locations locations = nearBy.getLocations().get(position);
        // Creating MarkerOptions
        options = new MarkerOptions();
        LatLng markerPosition = new LatLng(Double.valueOf(locations.getLatitude()), Double.valueOf(locations.getLongitude()));
        // Setting the videoPlayPosition of the marker
        options.position(markerPosition);
        /**
         * For the start location, the color of marker is GREEN and
         * for the end location, the color of marker is RED.
         */
        options.icon(BitmapDescriptorFactory.fromBitmap(getBitmapMarker(locations.getName(), 0)));
        //options.title(locationRanges.getName());
        // Add new marker to the Google Map Android API V2
        Marker marker = mMap.addMarker(options);
        // marker.showInfoWindow();
        marker.setTag(position);
    }

    findDistanceAndMarkDirection(nearBy.getLocations().get(locationPosition));

}

public Bitmap getBitmapMarker(String title, int id) {
    View customMarkerView = this.getLayoutInflater().inflate(R.layout.layout_marker_with_title, null);
    customMarkerView.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
    customMarkerView.layout(0, 0, customMarkerView.getMeasuredWidth(), customMarkerView.getMeasuredHeight());

    TextView tvMarkerProjectName = (TextView) customMarkerView.findViewById(R.id.tv_marker_project_name);
    if (id != 0) {
        ImageView ivMarkerImage = (ImageView) customMarkerView.findViewById(R.id.iv_marker_image);
        ivMarkerImage.setImageResource(id);
    }

    tvMarkerProjectName.setText(title);
    customMarkerView.setDrawingCacheEnabled(true);
    customMarkerView.buildDrawingCache();
    Bitmap bm = customMarkerView.getDrawingCache();
    return bm;
}


private void findDistanceAndMarkDirection(Locations destinationLocation) {
    flagCalculatingPath = true;
    if (polyline != null) {
        polyline.remove();
    }
    trPlaceTimeKm.setVisibility(View.INVISIBLE);
    tvPlaceDestinationName.setText(destinationLocation.getName());
    // Checks, whether start and end locationRanges are captured
    LatLng latLngDest = new LatLng(Double.valueOf(destinationLocation.getLatitude()), Double.valueOf(destinationLocation.getLongitude()));
    LatLng origin = listMarkerPoints.get(0);

    // Getting URL to the Google Directions API
    String url = getUrl(origin, latLngDest);
    //Log.d("onMapClick", url.toString());
    fetchUrl = new FetchUrl();

    // Start downloading json data from Google Directions API
    fetchUrl.execute(url);
    //move map camera
    mMap.moveCamera(CameraUpdateFactory.newLatLng(origin));
    mMap.animateCamera(CameraUpdateFactory.zoomTo(12));
}

private void setPathInfo(String duration, String distance, PolylineOptions polylineOptions, String destName) {
    tvPlaceTime.setText(duration);
    tvPlaceKmDistance.setText(distance);
    polyline = mMap.addPolyline(polylineOptions);
    tvPlaceDestinationName.setText(destName);
}

private String getUrl(LatLng origin, LatLng dest) {

    // Origin of route
    String str_origin = "origin=" + origin.latitude + "," + origin.longitude;

    // Destination of route
    String str_dest = "destination=" + dest.latitude + "," + dest.longitude;


    // Sensor enabled
    String sensor = "sensor=false";

    // Building the parameters to the web service
    String parameters = str_origin + "&" + str_dest + "&" + sensor;

    // Output format
    String output = "json";

    // Building the url to the web service
    String url = "https://maps.googleapis.com/maps/api/directions/" + output + "?" + parameters;


    return url;
}

/**
 * A method to download json data from url
 */
private String downloadUrl(String strUrl) throws IOException {
    String data = "";
    InputStream iStream = null;
    HttpURLConnection urlConnection = null;
    try {
        URL url = new URL(strUrl);

        // Creating an http connection to communicate with url
        urlConnection = (HttpURLConnection) url.openConnection();
        urlConnection.setReadTimeout(15000 /* milliseconds */);
        urlConnection.setConnectTimeout(15000 /* milliseconds */);
        urlConnection.setDoInput(true);
        // Connecting to url
        urlConnection.connect();

        // Reading data from url
        iStream = urlConnection.getInputStream();

        BufferedReader br = new BufferedReader(new InputStreamReader(iStream));

        StringBuffer sb = new StringBuffer();

        String line = "";
        while ((line = br.readLine()) != null) {
            sb.append(line);
        }

        data = sb.toString();
        //Log.d("downloadUrl", data.toString());
        br.close();

    } catch (Exception e) {
        // Log.d("Exception", e.toString());
    } finally {
        iStream.close();
        urlConnection.disconnect();
    }
    return data;
}


// Fetches data from url passed
private class FetchUrl extends AsyncTask<String, Void, String> {


    @Override
    protected void onCancelled() {
        //super.onCancelled();
    }

    @Override
    protected String doInBackground(String... url) {

        // For storing data from web service
        String data = "";

        try {
            // Fetching the data from web service
            data = downloadUrl(url[0]);
            //Log.d("Background Task data", data.toString());
        } catch (Exception e) {
            //  Log.d("Background Task", e.toString());
        }
        return data;
    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);

        if (!TextUtils.isEmpty(result)) {

            ParserTask parserTask = new ParserTask();

            // Invokes the thread for parsing the JSON data
            parserTask.execute(result);
        } else {
            flagCalculatingPath = false;
        }

    }
}

/**
 * A class to parse the Google Places in JSON format
 */
private class ParserTask extends AsyncTask<String, Integer, List<List<HashMap<String, String>>>> {

    // Parsing the data in non-ui thread
    @Override
    protected List<List<HashMap<String, String>>> doInBackground(String... jsonData) {

        JSONObject jObject;
        List<List<HashMap<String, String>>> routes = null;

        try {
            jObject = new JSONObject(jsonData[0]);
            //Log.d("ParserTask", jsonData[0].toString());
            DataParser parser = new DataParser();
            //Log.d("ParserTask", parser.toString());

            // Starts parsing data
            routes = parser.parse(jObject);
            //Log.d("ParserTask", "Executing routes");
            //Log.d("ParserTask", routes.toString());

        } catch (Exception e) {
            //Log.d("ParserTask", e.toString());
            e.printStackTrace();
        }
        return routes;
    }

    // Executes in UI thread, after the parsing process
    @Override
    protected void onPostExecute(List<List<HashMap<String, String>>> result) {
        ArrayList<LatLng> points;
        PolylineOptions lineOptions = null;
        HashMap<String, Object> hashMapDistancePathInfo = null;

        // Traversing through all the routes
        for (int i = 0; i < result.size(); i++) {
            points = new ArrayList<>();
            lineOptions = new PolylineOptions();


            // Fetching i-th route
            List<HashMap<String, String>> path = result.get(i);

            // Fetching all the points in i-th route
            for (int j = 1; j < path.size(); j++) {
                HashMap<String, String> point = path.get(j);

                double lat = Double.parseDouble(point.get("lat"));
                double lng = Double.parseDouble(point.get("lng"));
                LatLng position = new LatLng(lat, lng);

                points.add(position);
            }

            // Adding all the points in the route to LineOptions
            lineOptions.addAll(points);
            lineOptions.width(5);
            lineOptions.color(Color.RED);
            tvPlaceTime.setText(path.get(0).get("duration"));
            tvPlaceKmDistance.setText(path.get(0).get("distance"));
            trPlaceTimeKm.setVisibility(View.VISIBLE);

            hashMapDistancePathInfo = new HashMap<>();
            hashMapDistancePathInfo.put("duration", path.get(0).get("duration"));
            hashMapDistancePathInfo.put("distance", path.get(0).get("distance"));
            hashMapDistancePathInfo.put("polyLineOptions", lineOptions);
            //Log.d("onPostExecute", "onPostExecute lineoptions decoded");

        }
        // Drawing polyline in the Google Map for the i-th route
        if (lineOptions != null) {
            mapDistancePathData.put(locationPosition, hashMapDistancePathInfo);
            polyline = mMap.addPolyline(lineOptions);
        } else {
            //Log.d("onPostExecute", "without Polylines drawn");
        }
        flagCalculatingPath = false;
    }

}

protected synchronized void buildGoogleApiClient() {
    mGoogleApiClient = new GoogleApiClient.Builder(getApplicationContext())
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();
    mGoogleApiClient.connect();
}

@Override
public void onConnected(Bundle bundle) {

    mLocationRequest = new LocationRequest();
    mLocationRequest.setInterval(1000);
    mLocationRequest.setFastestInterval(1000);
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    locationListenerFinder = new LocationListenerFinder(this);
    if (locationPermission) {
        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, locationListenerFinder);
    }
}

@Override
public void onConnectionSuspended(int i) {
    mLocationRequest = null;
}

@Override
public void onLocationChanged(Location location) {

    mLastLocation = location;
    if (mCurrLocationMarker != null) {
        mCurrLocationMarker.remove();
    }
    int size = listNearByFacility.get(0).getNearBy().get(facilityPosition).getLocations().size();
    ivMyLocation.setVisibility(View.VISIBLE);

    //Place current location marker
    LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
    MarkerOptions markerOptions = new MarkerOptions();
    markerOptions.position(latLng);
    markerOptions.icon(BitmapDescriptorFactory.fromBitmap(getBitmapMarker("Current Location", R.drawable.ic_marker_blue)));

    //MarkerOptions markerOptions = new MarkerOptions();
    //markerOptions.videoPlayPosition(latLng);
    //markerOptions.title("Current Location");
    //markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));
    mCurrLocationMarker = mMap.addMarker(markerOptions);
    mCurrLocationMarker.setTag(size + 1);

    //move map camera
    // mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
    //mMap.animateCamera(CameraUpdateFactory.zoomTo(11));

    if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
        LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, locationListenerFinder);
        mGoogleApiClient.disconnect();
        mGoogleApiClient.unregisterConnectionCallbacks(this);
        mGoogleApiClient.unregisterConnectionFailedListener(this);
        //locationListener.clearData();
        mLocationRequest = null;
        locationListenerFinder = null;
    }
    mGoogleApiClient = null;
}

@Override
public void onConnectionFailed(ConnectionResult connectionResult) {

}

public void checkLocationPermission() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (!Utility.isPermissionAllowed(this, Manifest.permission.ACCESS_FINE_LOCATION)) {
            Utility.showPermissionDialog(this, Manifest.permission.ACCESS_FINE_LOCATION, BookingKARConstants.PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
            locationPermission = false;
            return;
        } else {
            locationPermission = true;
            return;
        }
    }
    locationPermission = true;
}

@Override
public void onRequestPermissionsResult(int requestCode,
                                       String permissions[], int[] grantResults) {
    //Checking the request code of our request
    if (requestCode == BookingKARConstants.PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION) {
        // If request is cancelled, the result arrays are empty.
        if (grantResults.length > 0
                && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

            // permission was granted. Do the
            locationPermission = true;
            if (mGoogleApiClient == null) {
                buildGoogleApiClient();
                checkLocationStatus();
            }
            loadMap();
            //mMap.setMyLocationEnabled(true);
        } else {

            // Permission denied, Disable the functionality that depends on this permission.
            Toast.makeText(this, "permission denied", Toast.LENGTH_LONG).show();
            finish();
        }
        return;
    }

    // other 'case' lines to check for other permissions this app might request.
    // You can add here other case statements according to your requirement.
}

private void checkLocationStatus() {
    LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    boolean gps_enabled = false;
    boolean network_enabled = false;

    try {
        gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
    } catch (Exception ex) {
    }

    try {
        network_enabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
    } catch (Exception ex) {
    }

    if (!gps_enabled && !network_enabled) {
        // notify user
        AlertDialog.Builder dialog = new AlertDialog.Builder(this);
        dialog.setMessage(getResources().getString(R.string.gps_network_not_enabled));
        dialog.setPositiveButton(getResources().getString(R.string.open_location_settings), new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface paramDialogInterface, int paramInt) {
                // TODO Auto-generated method stub
                Intent myIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                startActivity(myIntent);
                //get gps
            }
        });
        dialog.setNegativeButton(getString(R.string.Cancel), new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface paramDialogInterface, int paramInt) {
                // TODO Auto-generated method stub

            }
        });
        dialog.show();
    }
}

/*class WeakLocationListener implements LocationListener {

    private final WeakReference<LocationListener> locationListenerRef;

    public WeakLocationListener(@NonNull LocationListener locationListener) {
        locationListenerRef = new WeakReference<>(WeakLocationListener.this);
    }

    @Override
    public void onLocationChanged(android.location.Location location) {
        if (locationListenerRef.get() == null) {
            return;
        }
        locationListenerRef.get().onLocationChanged(location);
    }

    public interface onLocationChanged {
        void onLocationChanged(Location location);
    }

    public void clearData() {
        if (locationListenerRef.get() != null) {
            locationListenerRef.clear();
        }
    }*/

//}

}


1
答案在2018年2月更新,但未注意到LocationListener现已弃用(自Google Play服务11起)。 - Simon Hutton

0
@Override
public void onDestroy() {
    super.onDestroy();
    mLocationManager.removeUpdates(locationListener);
}

你仍然可能遇到内存泄漏问题。 - Ege Kuzubasioglu
对我来说它仍然在泄漏。 - Arun P M

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