260 260 - 1 year ago 37
Java Question

java: Is there any way to avoid writing named class? (variable has not been initialized)

In one place (and only one) i need a wrapper around the interface passed to the method. If possible I would like to avoid complicating the code by writing separate class for that purpose, so I wanted to take a closure approach, but then I run into "variable may not have been initialized" error.

I've found similar problem ( Final Local Variable may not have been initialized in anonymous inner class ), but If possible I would like to find a way to go around the problem without writing separate class for the wrapper.

the code:

protected void startListening(LocationRequest request,@Nullable final LocationListener listener) {
final LocationListener l = new LocationListener() {
public void onLocationChanged(Location location) {
if(listener != null) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, l);
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, request, l);

Additional details:

  • listener passed as a parameter may not have access to the google api client (I use few different ways to provide 'desired location', and just re-use the LocationListener interface in other implementations), so I cannot remove it from location updates from it's onLocationChanged method

  • there may possibly be more than one listener, so I cannot keep it in a class-level variable (I would have to use some collection, and logic to inform which one requested what and when)

  • the usual use-case for location requests in this code is to get a single location update upon user's action (e.g. opening the map, or clicking "refresh" button) - that's why i want to remove listener right away.

Answer Source

Instead of trying to pass the local variable l to removeLocationUpdates(), which is what triggers the error, just pass this as the argument. That works because in the context of that anonymous class, this refers to the anonymous class instance(LocationListener)

LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);