0

I have the following code :

@Override
public void onReceive(Context arg0, Intent arg1) 
{
    String blabla = "blabla";
    Handler connectionStatusHandler = new Handler() 
    {
        @Override
        public void handleMessage(Message msg) 
        {
            //Do something with blabla;
        }

    };
}

Unfortunatly it doesn't work because of the way java handles closures, i can't make blabla final.

So i thought maybe i can do something like this

@Override
public void onReceive(Context arg0, Intent arg1) 
{
    String blabla = "blabla";
    Handler connectionStatusHandler = new Handler() 
    {
        @Override
        public void handleMessage(Message msg) 
        {
            //Do something with localBlabla;
        }

        public String localBlabla;
    };

    connectionStatusHandler.localBlabla = blabla;
}

But it doesn't work also because Handler doesn't have a member called localBlabla.

Technically I can create a not anonymous class that inherits from Handler and add there the members I want, but before i do that i wonder maybe someone has some trick to solve it and pass non-final data to inner class

Thanks

OopsUser
  • 4,642
  • 7
  • 46
  • 71
  • Why can't you make `blabla` final? I don't see any reason not to add `final` to the declaration. – fabian Nov 27 '14 at 14:48
  • I want him to have reference to the variable, maybe when the handler will be called blabla would change his value to something else. – OopsUser Nov 27 '14 at 14:55
  • You could still copy the current value of `blabla` to a final variable. – fabian Nov 27 '14 at 14:59

2 Answers2

2

A quick and dirty hack is to use a final String[] with only one value. That way the value is still mutable, but you can use it anywhere you need a final:

@Override
public void onReceive(Context arg0, Intent arg1) 
{
    final String[] blabla = new String[] { "blabla" };
    Handler connectionStatusHandler = new Handler() 
    {
        @Override
        public void handleMessage(Message msg) 
        {
            blabla[0] = "new string value";
        }

    };
    blabla[0] = "i'm still editable";
}

This was originally thought up by someone who wanted a wrapper class, similar to a Reference, or c++ pointers, but was too lazy to write out the full interface.

I recommend NOT using this in any code you intend to be maintanable. You can come up with much cleaner, clearer options if you write just a bit more boilerplate.

blgt
  • 8,135
  • 1
  • 25
  • 28
0

You can make a new class, call it something like MyConnectionStatusHandler, and create a public constructor for it to get the message and store it. Then use new MyConnectionStatusHandler(blabla) instead of new Handler(){...}.

Edit: I have tried doing stuff like this before, and it either doesn't work or becomes a mess. Creating a non-anonymous class is probably your best choice.

James Westman
  • 2,680
  • 1
  • 15
  • 20