| 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> |
| |
| |