I was using setId
method of View
class. According to this method
public void setId(@IdRes int id) // This will accept resource id
When I tried to use this method with some hardcoded int
value(let say 100), then this method start throwing correct warning which is expected-
actionButton.setId(100);
Expected resource of type id.
But when I converted this hardcoded value into a method and never defined that this method will return @IdRes
, Warning gets silent.
private int getViewId() { return 100; }
Method call to set Id.
actionButton.setId(getViewId());
Isn't both are same. Hardcoded int
and a int
return from this method. So why in one case method throwing warning and in another it gets silent.
For a sake I tried with StringRes
but I am getting warning in both cases.
private void setMyString(@StringRes int resourceString) {}
Warning in both below cases-
setMyString(1); setMyString(getStringId()); getStringId returns int value
2 Answers
Answers 1
It is just a Lint warning since the method expects a variable to be from R.id class.
Regarding the case of value returned from a method, Lint doesn't bother to check the whole function whether it is returning a hardcoded integer or an actual id.
From the documentation of @IdRes it states:
Denotes that an integer parameter, field or method return value is expected to be an id resource reference (e.g. android.R.id.copy).
Also the annotation just exist in the source code for documentation. After the code is compiled, the annotation will be removed.
Answers 2
In one case (@IdRes
) you are calling a method from the API (View.setId()
), while in the other, you are calling a method in your own code. Also getViewId()
is not annotated, so it is not obvious from the signature what kind of int it returns.
With the following methods :
private int getUndefinedRes() { ... } private @IdRes int getIdRes() { ... } private @StringRes int getStringRes() { ... } private void setMyString(@StringRes int resourceString) { } private void setMyId(@IdRes int resourceId) { }
The lint and inspection results are (as of Android Studio 2.3.3) :
// API method with definitely wrong value (constant) // --> ERROR new View(context).setId(100); new TextView(context).setText(100); // API method with definitely wrong value (from method declaration) // --> ERROR new View(context).setId(getStringRes()); new TextView(context).setText(getIdRes()); // API method with potentially wrong value // --> ok new View(context).setId(getUndefinedRes()); new TextView(context).setText(getUndefinedRes()); // own method with potentially wrong value // --> ERROR setMyString(getUndefinedRes()); setMyId(getUndefinedRes());
It seems that the lint only looks at the method signature.
It is also more lenient when you call an API method : it shows an error only if it is obvious that you are doing something wrong. I think that it's because doing otherwise would force everybody to add a lot of annotations.
On the other hand, when you add annotations in your code, you are opting in for the additionnal severity.
0 comments:
Post a Comment