Given an @EIntentService like so:
@EIntentService
public class FooIntentService extends IntentService {
@ServiceAction
public void foo(Object foo) { /* ... */ }
}
Compilation fails annotation processing with the following error, which is misleading:
error: method foo(Object) is already defined in class IntentBuilder_
This is because the generated code in FooIntentService_.java has this bit (see comments in code block):
public FooIntentService_.IntentBuilder_ foo(Object foo) {
intent_.setAction(ACTION_FOO);
foo(foo); // <--- Recursive call!!!
return this;
}
public FooIntentService_.IntentBuilder_ foo(Object foo) { // <--- Because of this
intent_.putExtra(FOO_EXTRA, ((Serializable) foo);
return this;
}
And when the parameter name is changed, the Extra is properly passed.
public FooIntentService_.IntentBuilder_ foo(Object bar) {
intent_.setAction(ACTION_FOO);
bar(bar); // <--- Happy now
return this;
}
public FooIntentService_.IntentBuilder_ bar(Object bar) { // <--- Because, this.
intent_.putExtra(BAR_EXTRA, ((Serializable) bar);
return this;
}
Since the @EIntentService usage is defined as:
FooIntentService_.intent(getContext()).foo(new Whatever()).start();
I think having public accessors for the Extras generated from the parameters of the annotated methods is unnecessary. They only pollute the IntentBuilder_s namespace since they'll never be used directly.
I think a better way to do this would be, in this case, to make those Extras private, and use a different naming scheme while generating them so they won't collide with the annotated methods...
Or, maybe changing the usage to something like the following is better?
FooIntentService_.intent(getContext()) //
.foo(/* NO PARAMETERS */).bar(new Whatever()) // .bar() is really the parameter to .foo()
.start();
so those Extra methods handling the parameters would make sense.
Either of those, or @ServiceAction annotation's processor might warn users when it's placed on a method that has a parameter name the same as its name.