| page.title=Improving Code Inspection with Annotations | |
| @jd:body | |
| <div id="qv-wrapper"> | |
| <div id="qv"> | |
| <h2>In this document</h2> | |
| <ol> | |
| <li><a href="#adding-nullness">Adding Nullness Annotations</a></li> | |
| <li><a href="#res-annotations">Adding Resource Annotations</a></li> | |
| <li><a href="#thread-annotations">Adding Thread Annotations</a></li> | |
| <li><a href="#value-constraint">Adding Value Constraint Annotations</a></li> | |
| <li><a href="#permissions">Adding Permission Annotations</a></li> | |
| <li><a href="#check-result">Adding CheckResult Annotations</a></li> | |
| <li><a href="#call-super">Adding CallSuper Annotations</a></li> | |
| <li><a href="#enum-annotations">Creating Enumerated Annotations</a></li> | |
| </ol> | |
| <h2>See also</h2> | |
| <ol> | |
| <li><a href="{@docRoot}tools/help/lint.html">lint (reference)</a></li> | |
| <li><a href="{@docRoot}tools/debugging/improving-w-lint.html">Improving Your Code with lint</a></li> | |
| <li><a href="{@docRoot}tools/studio/index.html#annotations">Annotations in Android Studio</a></li> | |
| </ol> | |
| </div> | |
| </div> | |
| <p>Using code inspections tools such as <a href="{@docRoot}tools/help/lint.html">lint</a> can help | |
| you find problems and improve your code, but inspection tools can only infer so much. Android | |
| resource ids, for example, use an {@code int} to identify strings, graphics, colors and other | |
| resource types, so inspection tools cannot tell when you have specified a string resource where | |
| you should have specified a color. This situation means that your app may render incorrectly or | |
| fail to run at all, even if you use code inspection. </p> | |
| <p>Annotations allow you to provide hints to code inspections tools like {@code lint}, to help | |
| detect these, more subtle code problems. They are added as metadata tags that you attach to | |
| variables, parameters, and return values to inspect method return values, passed parameters, and | |
| local variables and fields. When used with code inspections tools, annotations can help you detect | |
| problems, such as null pointer exceptions and resource type | |
| conflicts. </p> | |
| <p>For more information on enabling <a href="{@docRoot}tools/help/lint.html">lint</a> inspections | |
| and running <a href="{@docRoot}tools/help/lint.html">lint</a>, | |
| see <a href="{@docRoot}tools/debugging/improving-w-lint.html">Improving Your Code with lint</a>.</p> | |
| <p>Android supports a variety of annotations for insertion in the methods, parameters, and return | |
| values in your code, for example:</p> | |
| <dl> | |
| <dt>{@link android.support.annotation.Nullable @Nullable}</dt> | |
| <dd>Can be null.</dd> | |
| <dt>{@link android.support.annotation.NonNull @NonNull}</dt> | |
| <dd>Cannot be null.</dd> | |
| <dt>{@link android.support.annotation.StringRes @StringRes}</dt> | |
| <dd>References a <a href="{@docRoot}reference/android/R.string.html"><code>R.string</code></a> | |
| resource.</dd> | |
| <dt>{@link android.support.annotation.DrawableRes @DrawableRes}</dt> | |
| <dd>References a | |
| <a href="{@docRoot}guide/topics/resources/drawable-resource.html"><code>Drawable</code></a> | |
| resource. </dd> | |
| <dt>{@link android.support.annotation.ColorRes @ColorRes}</dt> | |
| <dd>References a <a href="{@docRoot}reference/android/graphics/Color.html"><code>Color</code></a> | |
| resource. </dd> | |
| <dt>{@link android.support.annotation.InterpolatorRes @InterpolatorRes}</dt> | |
| <dd>References a | |
| <a href="{@docRoot}reference/android/view/animation/Interpolator.html"><code>Interpolator</code></a> | |
| resource. </dd> | |
| <dt>{@link android.support.annotation.AnyRes @AnyRes}</dt> | |
| <dd>References any type of <a href="{@docRoot}reference/android/R.html"><code>R.</code></a> | |
| resource. </dd> | |
| <dt><code>@UiThread</code></dt> | |
| <dd>Calls from a UI | |
| <a href="{@docRoot}guide/components/processes-and-threads.html">thread</a>. </dd> | |
| </dl> | |
| <p>For a complete list of the supported annotations, either examine the contents of the | |
| {@link android.support.annotation Support-Annotations} library or use the | |
| auto-complete feature to display the available options for the <code>import | |
| android.support.annotation.</code> statement. The | |
| <a href="{@docRoot}tools/help/sdk-manager.html"> SDK Manager</a> packages the | |
| {@link android.support.annotation Support-Annotations} library in the Android Support Repository | |
| for use with Android Studio and in the Android | |
| <a href="{@docRoot}tools/support-library/index.html">Support Library</a> for use with other Android | |
| development tools.</p> | |
| <p>To add annotations to your code, first add a dependency to the | |
| {@link android.support.annotation Support-Annotations} library. In Android Studio, | |
| add the dependency using the <strong>File > Project Structure > Dependencies</strong> menu | |
| option or your <code>build.gradle</code> file. The following example shows how to add the | |
| {@link android.support.annotation Support-Annotations} library dependency in the | |
| <code>build.gradle</code> file: </p> | |
| <pre> | |
| dependencies { | |
| compile 'com.android.support:support-annotations:22.2.0' | |
| } | |
| </pre> | |
| <p>The {@link android.support.annotation Support-Annotations} library is decorated with the | |
| supported annotations so using this library's methods and resources automatically checks the code | |
| for potential problems.</p> | |
| <p>If you include annotations in a library and use the | |
| <a href="{@docRoot}tools/building/plugin-for-gradle.html"><code>Android Plugin for Gradle</code></a> | |
| to build an Android ARchive (AAR) artifact of that library, the annotations are included as part | |
| of the artifact in XML format in the <code>annotations.zip</code> file. </p> | |
| <p>To start a code inspection from Android Studio, which includes validating annotations and | |
| automatic <a href="{@docRoot}tools/help/lint.html">lint</a> checking, select | |
| <strong>Analyze > Inspect Code</strong> from the menu options. Android Studio displays conflict | |
| messages throughout the code to indication annotation conflicts and suggest possible | |
| resolutions.</p> | |
| <h2 id="adding-nullness">Adding Nullness Annotations</h2> | |
| <p>Add {@link android.support.annotation.Nullable @Nullable} and | |
| {@link android.support.annotation.NonNull @NonNull} annotations to check | |
| the nullness of a given variable, parameter, or return value. For example, if a local variable | |
| that contains a null value is passed as a parameter to a method with the | |
| {@link android.support.annotation.NonNull @NonNull} annotation | |
| attached to that parameter, building the code generates a warning indicating a non-null conflict. </p> | |
| <p>This example attaches the {@link android.support.annotation.NonNull @NonNull} annotation to | |
| the <code>context</code> and <code>attrs</code> parameters to check that the passed parameter | |
| values are not null. </p> | |
| <pre> | |
| import android.support.annotation.NonNull; | |
| ... | |
| /** Add support for inflating the <fragment> tag. */ | |
| @NonNull | |
| @Override | |
| public View onCreateView(String name, @NonNull Context context, | |
| @NonNull AttributeSet attrs) { | |
| ... | |
| } | |
| ... | |
| </pre> | |
| <p class="note"><strong>Note:</strong> Android Studio supports running a nullability analysis to | |
| automatically infer and insert nullness annotations in your code. For more information about | |
| inferring nullability in Android Studio, see | |
| <a href="{@docRoot}tools/studio/index.html#annotations">Annotations in Android Studio</a>. </p> | |
| <h2 id="res-annotations">Adding Resource Annotations</h2> | |
| <p>Validating resource types can be useful as Android references to resources, such as | |
| <a href="{@docRoot}guide/topics/resources/drawable-resource.html"><code>Drawables</code></a> and | |
| <a href="{@docRoot}reference/android/R.string.html"><code>R.string</code></a> resources, are | |
| passed as integers. Code that expects a parameter to reference a specific type of resource, for | |
| example <a href="{@docRoot}guide/topics/resources/drawable-resource.html"><code>Drawables</code></a>, | |
| can be passed the expected reference type of <code>int</code>, but actually reference a different | |
| type of resource, such as a <code>R.string</code></a> resource. </p> | |
| <p>For example, add {@link android.support.annotation.StringRes @StringRes} annotations to check | |
| that a resource parameter contains a | |
| <a href="{@docRoot}reference/android/R.string.html"><code>R.string</code></a> | |
| reference. During code inspection, the annotation generates a warning if a <code>R.string</code> | |
| reference is not passed in the parameter.</p> | |
| <p>This example attaches the {@link android.support.annotation.StringRes @StringRes} | |
| annotation to the <code>resId</code> parameter to validate that it is really a string resource. </p> | |
| <pre> | |
| import android.support.annotation.StringRes; | |
| ... | |
| public abstract void setTitle(@StringRes int resId); | |
| ... | |
| </pre> | |
| <p>Annotations for the other resource types, such as | |
| {@link android.support.annotation.DrawableRes @DrawableRes}, | |
| {@link android.support.annotation.DimenRes @DimenRes}, | |
| {@link android.support.annotation.ColorRes @ColorRes}, and | |
| {@link android.support.annotation.InterpolatorRes @InterpolatorRes} can be added using | |
| the same annotation format and run during the code inspection. </p> | |
| <h2 id="thread-annotations">Adding Thread Annotations</h2> | |
| <p>Thread annotations check if a method is called from a specific type of | |
| <a href="{@docRoot}guide/components/processes-and-threads.html">thread</a>. The following thread | |
| annotations are supported: </p> | |
| <ul> | |
| <li><code>@UiThread</code> </li> | |
| <li><code>@MainThread</code> </li> | |
| <li><code>@WorkerThread</code> </li> | |
| <li><code>@BinderThread</code> | |
| </ul> | |
| <p class="note"><strong>Note:</strong> The <code>@MainThread</code> | |
| and the <code>@UiThread</code> annotations are interchangeable so | |
| methods calls from either thread type are allowed for these annotations. </p> | |
| <p>If all methods in a class share the same threading requirement, you can add a single | |
| <a href="{@docRoot}guide/components/processes-and-threads.html">thread</a> | |
| annotation to the class to verify that all methods in the class are called from the same type of | |
| <a href="{@docRoot}guide/components/processes-and-threads.html">thread</a>. </p> | |
| <p>A common use of the <a href="{@docRoot}guide/components/processes-and-threads.html">thread</a> | |
| annotation is to validate method overrides in the | |
| <a href="{@docRoot}reference/android/os/AsyncTask.html">AsyncTask</a> class as this class performs | |
| background operations and publishes results only on the UI | |
| <a href="{@docRoot}guide/components/processes-and-threads.html">thread</a>. </p> | |
| <h2 id="value-constraint">Adding Value Constraint Annotations</h2> | |
| <p>Use the <code>@IntRange</code>, | |
| <code>@FloatRange</code>, and | |
| <code>@Size</code> annotations to validate the values of passed | |
| parameters. </p> | |
| <p>The <code>@IntRange</code> annotation validates that the parameter | |
| value is within a specified range. The following example ensures that the <code>alpha</code> | |
| parameter contains an integer value from 0 to 255: </p> | |
| <pre> | |
| public void setAlpha(@IntRange(from=0,to=255) int alpha) { … } | |
| </pre> | |
| <p>The <code>@FloatRange</code> annotation checks that the parameter | |
| value is within a specified range of floating point values. The following example ensures that the | |
| <code>alpha</code> parameter contains a float value from 0.0 to 1.0: </p> | |
| <pre> | |
| public void setAlpha(@FloatRange(from=0.0, to=1.0) float alpha) {...} | |
| </pre> | |
| <p>The <code>@Size</code> annotation checks the size of a collection or | |
| array, as well as the length of a string. For example, use the <code>@Size(min=1)</code> | |
| annotation to check if a collection is not empty, and the <code>@Size(2)</code> annotation to | |
| validate that an array contains exactly two values. The following example ensures that the | |
| <code>location</code> array contains at least one element: </p> | |
| <pre> | |
| int[] location = new int[3]; | |
| button.getLocationOnScreen(@Size(min=1) location); | |
| </pre> | |
| <h2 id="permissions">Adding Permission Annotations</h2> | |
| <p>Use the <code>@RequiresPermission</code> annotation to | |
| validate the permissions of the caller of a method. To check for a single permission from a | |
| list the valid permissions, use the <code>anyOf</code> attribute. To check for a set of | |
| permissions, use the <code>allOf</code> attribute. The following example annotates the | |
| <code>setWallpaper</code> method to ensure that the caller of the method has the | |
| <code>permission.SET_WALLPAPERS</code> permission. </p> | |
| <pre> | |
| @RequiresPermission(Manifest.permission.SET_WALLPAPER) | |
| public abstract void setWallpaper(Bitmap bitmap) throws IOException; | |
| </pre> | |
| <p>This example requires the caller of the | |
| <code>updateVisitedHistory</code> method to have both read and write bookmark history permissions. </p> | |
| <pre> | |
| @RequiresPermission(allOf = { | |
| Manifest.permission.READ_HISTORY_BOOKMARKS, | |
| Manifest.permission.WRITE_HISTORY_BOOKMARKS}) | |
| public static final void updateVisitedHistory(ContentResolver cr, String url, boolean real) { | |
| ... | |
| } | |
| </pre> | |
| <h2 id="check-result">Adding CheckResults Annotations</h2> | |
| <p>Use the <code>@CheckResults</code> annotation to | |
| validate that a method's result or return value is actually used. The following example annotates | |
| the <code>checkPermissions</code> method to ensure the return value of the method is actually | |
| referenced. It also names the | |
| <a href="{@docRoot}reference/android/content/ContextWrapper.html#enforcePermission">enforcePermission</a> | |
| method as a method to be suggested to the developer as a replacement. </p> | |
| <pre> | |
| @CheckResult(suggest="#enforcePermission(String,int,int,String)") | |
| public abstract int checkPermission(@NonNull String permission, int pid, int uid); | |
| </pre> | |
| {@link android.support.annotation.StringDef @StringDef} | |
| <h2 id="call-super">Adding CallSuper Annotations</h2> | |
| <p>Use the <code>@CallSuper</code> annotation to validate that an | |
| overriding method calls the super implementation of the method. The following example annotates | |
| the <code>onCreate</code> method to ensure that any overriding method implementations call | |
| <code>super.onCreate()</code>. </p> | |
| <pre> | |
| @CallSuper | |
| protected void onCreate(Bundle savedInstanceState) { | |
| } | |
| </pre> | |
| <h2 id="enum-annotations">Creating Enumerated Annotations</h2> | |
| <p>Use the {@link android.support.annotation.IntDef @IntDef} and | |
| {@link android.support.annotation.StringDef @StringDef} annotations | |
| so you can create enumerated annotations of integer and string sets to validate other types of code | |
| references, such as passing references to a set of constants. </p> | |
| <p>The following example illustrates the steps to create an enumerated annotation that ensures | |
| a value passed as a method parameter references one of the defined constants.</p> | |
| <pre> | |
| import android.support.annotation.IntDef; | |
| ... | |
| public abstract class ActionBar { | |
| ... | |
| //Define the list of accepted constants | |
| @IntDef({NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS}) | |
| //Tell the compiler not to store annotation data in the <code>.class</code> file | |
| @Retention(RetentionPolicy.SOURCE) | |
| //Declare the <code>NavigationMode</code> annotation | |
| public @interface NavigationMode {} | |
| //Declare the constants | |
| public static final int NAVIGATION_MODE_STANDARD = 0; | |
| public static final int NAVIGATION_MODE_LIST = 1; | |
| public static final int NAVIGATION_MODE_TABS = 2; | |
| //Decorate the target methods with the annotation | |
| @NavigationMode | |
| public abstract int getNavigationMode(); | |
| //Attach the annotation | |
| public abstract void setNavigationMode(@NavigationMode int mode); | |
| </pre> | |
| <p>When you build this code, a warning is generated if the <code>mode</code> parameter does | |
| not reference one of the defined constants (<code>NAVIGATION_MODE_STANDARD</code>, | |
| <code>NAVIGATION_MODE_LIST</code>, or <code>NAVIGATION_MODE_TABS</code>).</p> | |
| <p>You can also define an annotation with a <code>flag</code> to check if a parameter | |
| or return value references a valid pattern. This example creates the | |
| <code>DisplayOptions</code> annotation with a list of valid <code>DISPLAY_</code> constants. </p> | |
| <pre> | |
| import android.support.annotation.IntDef; | |
| ... | |
| @IntDef(flag=true, value={ | |
| DISPLAY_USE_LOGO, | |
| DISPLAY_SHOW_HOME, | |
| DISPLAY_HOME_AS_UP, | |
| DISPLAY_SHOW_TITLE, | |
| DISPLAY_SHOW_CUSTOM | |
| }) | |
| @Retention(RetentionPolicy.SOURCE) | |
| public @interface DisplayOptions {} | |
| ... | |
| </pre> | |
| <p>When you build code with an annotation flag, a warning is generated if the decorated parameter | |
| or return value does not reference a valid pattern.</p> | |