[Groovy] SaveInstance on SwissKnife

It's been a couple of months since I started trying out the all the goods that the programming language called Groovy offers to everyone.

If anyone doesn't know about it, or wants to see some of the best things it can offer, I reccomend you taking a look at the post Arasthel made about it: Why is Java old (Spanish).

As you will know if you've read Arasthel's post, there is a plugin (still in beta) which adds support for writing Android applications using Groovy.
And taking into account that Android Studio offers native compatibility with Groovy, one only needs to be crazy enough to try it.

SwissKnife

SwissKnife

There always exists people who are crazy enough to develop libraries using a language in Beta state (and no, I'm not talking about Swift) which will be used in a non-natively-supported environment. And that's how SwissKnife appeared.

I suppose that if you develop for Android you'll have heard about AndroidAnnotations and ButterKnife, two famous libraries that contain their power in their use by annotations.

If you are developing for Android using Groovy, I'm sorry to tell you that you won't be able to use them, as they only work in Java. And that's where SwissKnife comes into action.

As a little summary (you can read more information at its official README), SwissKnife provides an AndroidAnnotations+ButterKife functionality, ported natively to Groovy.

It provides very useful methods, such as @InjectView and @OnClick, and recently we've added the @SaveInstance method, the one we'll be talking about in this post.

@SaveInstance

Anybody who has worked with Android and has needed to keep a variable's state in a state change (such as a screen rotation) has needed to mess with a code that looks like this:

@Override
public void onSaveInstanceState(Bundle outState){
    super.onSaveInstanceState(outState);
    outState.putInteger("MY_INTEGER", myInteger);
}

And then, its corresponding state recover:

@Override
public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    // Your code
    if(savedInstanceState != NULL){
	    myInteger = savedInstanceState.getInteger("MY_INTEGER");
    }
}

As this code is very tedious and repetitive, Arasthel came to the idea of creating the @SaveInstance for getting rid of it.
After some days of work (from here: thanks to Cédric Champeau and Guillaume Laforge, members of the Groovy development team) the result looks like this:

@SaveInstance
public int myInteger

@Override
public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    SwissKnife.restoreState(this, savedInstanceState);
}

And that's all. Without having to override manually the onSaveInstanceState method, without having to check if saveInstanceState was null or not...

Then we only need to call SwissKnife.restoreState(this, savedInstanceState) and enjoy watching how SwissKnife makes all the work without we even noticing that.

Also, in case that we needed to assign a specific tag to a specific variable, we can make it just by passing the tag as a parameter to the annotation:

@SaveInstance("MY_INTEGER")
public int myInteger

Is also worth saying that it will also work both if we have overrided manually the onSaveInstanceState method, or we haven't declared it at all.

Of course, @SaveInstance supports any type of element that can be written to a Bundle Object.

@SaveInstance Documentation

And one more thing...

@SaveInstance can be also used in order to keep a View's state during a state change.
Android already does it by default, but only if the View has an associated id.
With @SaveInstance, the state saving and restoring can be forced even with Views without an associated id.

@InjectView(R.id.edit_text)
@SaveInstance
public EditText myText;