242 lines
10 KiB
Plaintext
242 lines
10 KiB
Plaintext
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 Annotation</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>
|
|
</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 to your <code>build.gradle</code> file. </p>
|
|
|
|
<pre>
|
|
dependencies {
|
|
compile 'com.android.support:support-annotations:22.0.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>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>Validating resource types can be useful as Android references to
|
|
<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 both
|
|
passed as integers. Code that expects a parameter to reference a <code>Drawable</code> can be passed
|
|
the expected reference type of int, but actually reference a <code>R.string</code></a> resource. </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.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="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>
|
|
|
|
|