Mit Code-Prüftools wie lint können Sie Probleme finden und Ihren Code verbessern. Allerdings können Prüftools nur so viel ableiten. Android-Ressourcen-IDs verwenden beispielsweise ein int
, um Strings, Grafiken, Farben und andere Ressourcentypen zu identifizieren. Daher können Prüftools nicht erkennen, wenn Sie eine String-Ressource angegeben haben, obwohl Sie eine Farbe hätten angeben sollen. Das bedeutet, dass Ihre App möglicherweise falsch gerendert wird oder überhaupt nicht ausgeführt werden kann, selbst wenn Sie die Codeüberprüfung verwenden.
Mit Anmerkungen können Sie Code-Prüftools wie Lint Hinweise geben, um diese subtileren Codeprobleme zu erkennen. Anmerkungen werden als Metadatentags hinzugefügt, die Sie an Variablen, Parameter und Rückgabewerte anhängen, um Methodenrückgabewerte, übergebene Parameter, lokale Variablen und Felder zu prüfen. In Kombination mit Tools zur Codeüberprüfung können Sie mit Anmerkungen Probleme wie NullPointerException und Konflikte mit Ressourcentypen erkennen.
Android unterstützt eine Vielzahl von Annotationen über die Jetpack Annotations Library.
Sie können über das Paket androidx.annotation
auf die Bibliothek zugreifen.
Hinweis:Wenn ein Modul von einem Annotationsprozessor abhängt, müssen Sie entweder die Abhängigkeitskonfiguration kapt
oder ksp
für Kotlin oder die Abhängigkeitskonfiguration annotationProcessor
für Java verwenden, um diese Abhängigkeit hinzuzufügen.
Anmerkungen zum Projekt hinzufügen
Wenn Sie Annotationen in Ihrem Projekt aktivieren möchten, fügen Sie Ihrer Bibliothek oder App die androidx.annotation:annotation
-Abhängigkeit hinzu. Alle Annotationen, die Sie hinzufügen, werden überprüft, wenn Sie eine Codeüberprüfung oder einen lint
-Task ausführen.
Jetpack Annotations-Bibliotheksabhängigkeit hinzufügen
Die Jetpack Annotations-Bibliothek wird im Maven-Repository von Google veröffentlicht.
Wenn Sie die Jetpack Annotations-Bibliothek in Ihr Projekt einfügen möchten, fügen Sie die folgende Zeile in den dependencies
-Block Ihrer build.gradle
- oder build.gradle.kts
-Datei ein:
Kotlin
dependencies { implementation("androidx.annotation:annotation:1.9.1") }
Groovy
dependencies { implementation 'androidx.annotation:annotation:1.9.1' }
Wenn Sie in Ihrem eigenen Bibliotheksmodul Anmerkungen verwenden, werden diese als Teil des AAR-Artefakts (Android Archive) im XML-Format in der Datei annotations.zip
eingefügt. Wenn Sie die androidx.annotation
-Abhängigkeit hinzufügen, wird keine Abhängigkeit für nachgelagerte Nutzer Ihrer Bibliothek eingeführt.
Hinweis:Wenn Sie andere Jetpack-Bibliotheken verwenden, müssen Sie die androidx.annotation
-Abhängigkeit möglicherweise nicht hinzufügen. Da viele andere Jetpack-Bibliotheken von der Annotations Library abhängen, haben Sie möglicherweise bereits Zugriff auf die Annotationen.
Eine vollständige Liste der im Jetpack-Repository enthaltenen Annotationen finden Sie in der Referenz zur Jetpack Annotations-Bibliothek. Alternativ können Sie die automatische Vervollständigung verwenden, um die verfügbaren Optionen für die import androidx.annotation.
-Anweisung aufzurufen.
Codeüberprüfungen ausführen
Wenn Sie eine Codeüberprüfung in Android Studio starten möchten, bei der auch Anmerkungen validiert und automatische Lint-Prüfungen durchgeführt werden, wählen Sie im Menü Analysieren > Code prüfen aus. In Android Studio werden Konfliktmeldungen angezeigt, um auf potenzielle Probleme hinzuweisen, bei denen Ihr Code mit Anmerkungen in Konflikt steht, und um mögliche Lösungen vorzuschlagen.
Sie können Anmerkungen auch erzwingen, indem Sie den lint
-Task über die Befehlszeile ausführen. Das kann zwar nützlich sein, um Probleme mit einem Continuous Integration-Server zu kennzeichnen, die Aufgabe lint
erzwingt jedoch keine Nullable-Annotationen (siehe nächster Abschnitt). Das macht nur Android Studio. Weitere Informationen zum Aktivieren und Ausführen von Lint-Prüfungen finden Sie unter Code mit Lint-Prüfungen verbessern.
Durch Annotationskonflikte werden zwar Warnungen generiert, diese verhindern aber nicht, dass Ihre App kompiliert wird.
Nullable-Annotationen
Nullable-Annotationen können in Java-Code nützlich sein, um zu erzwingen, ob Werte null sein dürfen. In Kotlin-Code sind sie weniger nützlich, da Kotlin integrierte Regeln zur Null-Zulässigkeit hat, die zur Kompilierzeit erzwungen werden.Fügen Sie die Annotationen @Nullable
und @NonNull
hinzu, um zu prüfen, ob eine bestimmte Variable, ein Parameter oder ein Rückgabewert null ist. Die Anmerkung @Nullable
gibt eine Variable, einen Parameter oder einen Rückgabewert an, der null sein kann.
@NonNull
gibt eine Variable, einen Parameter oder einen Rückgabewert an, der nicht null sein kann.
Wenn beispielsweise eine lokale Variable, die einen Nullwert enthält, als Parameter an eine Methode übergeben wird, an die die Annotation @NonNull
angehängt ist, wird beim Erstellen des Codes eine Warnung ausgegeben, die auf einen Konflikt mit „non-null“ hinweist. Wenn Sie versuchen, auf das Ergebnis einer Methode zu verweisen, die mit @Nullable
gekennzeichnet ist, ohne zuerst zu prüfen, ob das Ergebnis null ist, wird eine Nullable-Warnung generiert. Verwenden Sie @Nullable
nur für den Rückgabewert einer Methode, wenn jede Verwendung der Methode explizit auf „null“ geprüft werden muss.
Das folgende Beispiel zeigt die Verwendung von Nullable-Typen in der Praxis. Im Kotlin-Beispielcode wird die Annotation @NonNull
nicht verwendet, da sie automatisch dem generierten Bytecode hinzugefügt wird, wenn ein nicht nullable-Typ angegeben wird. Im Java-Beispiel wird die Annotation @NonNull
für die Parameter context
und attrs
verwendet, um zu prüfen, ob die übergebenen Parameterwerte nicht null sind. Außerdem wird geprüft, ob die onCreateView()
-Methode selbst „null“ zurückgibt:
Kotlin
... /** Annotation not used because of the safe-call operator(?)**/ override fun onCreateView( name: String?, context: Context, attrs: AttributeSet ): View? { ... } ...
Java
import androidx.annotation.NonNull; ... /** Add support for inflating the <fragment> tag. **/ @NonNull @Override public View onCreateView(String name, @NonNull Context context, @NonNull AttributeSet attrs) { ... } ...
Null-Zulässigkeitsanalyse
Android Studio unterstützt die Ausführung einer Nullable-Analyse, um Nullable-Annotationen automatisch abzuleiten und in Ihren Code einzufügen. Bei einer Nullable-Analyse werden die Verträge in den Methodenhierarchien in Ihrem Code gescannt, um Folgendes zu erkennen:
- Aufrufen von Methoden, die „null“ zurückgeben können
- Methoden, die nicht „null“ zurückgeben sollten.
- Variablen wie Felder, lokale Variablen und Parameter, die null sein können.
- Variablen wie Felder, lokale Variablen und Parameter, die keinen Nullwert enthalten können.
Bei der Analyse werden dann automatisch die entsprechenden Null-Annotationen an den erkannten Stellen eingefügt.
Wenn Sie eine Nullable-Analyse in Android Studio ausführen möchten, wählen Sie Analyze > Infer Nullity aus. Android Studio fügt die Android-Annotationen @Nullable
und @NonNull
an den erkannten Stellen in Ihrem Code ein. Nachdem Sie eine Nullanalyse durchgeführt haben, sollten Sie die eingefügten Anmerkungen überprüfen.
Hinweis:Wenn Sie Nullable-Annotationen hinzufügen, schlägt die automatische Vervollständigung möglicherweise die IntelliJ-Annotationen
@Nullable
und @NotNull
anstelle der Android-Nullable-Annotationen vor und importiert die entsprechende Bibliothek automatisch. Der Android Studio-Lint-Checker sucht jedoch nur nach den Android-Null-Annotationen. Prüfen Sie beim Überprüfen Ihrer Anmerkungen, ob in Ihrem Projekt die Android-Null-Anmerkungen verwendet werden, damit Sie vom Lint-Checker während der Codeüberprüfung richtig benachrichtigt werden.
Ressourcenanmerkungen
Die Validierung von Ressourcentypen kann nützlich sein, da Android-Verweise auf Ressourcen wie drawable- und string-Ressourcen als Ganzzahlen übergeben werden.
Code, der erwartet, dass ein Parameter auf einen bestimmten Ressourcentyp verweist, z. B. auf String
, kann an den erwarteten Referenztyp int
übergeben werden, verweist aber tatsächlich auf einen anderen Ressourcentyp, z. B. auf eine R.string
-Ressource.
Fügen Sie beispielsweise @StringRes
-Annotationen hinzu, um zu prüfen, ob ein Ressourcenparameter einen R.string
-Verweis enthält, wie hier gezeigt:
Kotlin
abstract fun setTitle(@StringRes resId: Int)
Java
public abstract void setTitle(@StringRes int resId)
Bei der Codeüberprüfung wird durch die Annotation eine Warnung generiert, wenn keine R.string
-Referenz im Parameter übergeben wird.
Anmerkungen für andere Ressourcentypen wie @DrawableRes
, @DimenRes
, @ColorRes
und @InterpolatorRes
können mit demselben Anmerkungsformat hinzugefügt und während der Codeüberprüfung ausgeführt werden.
Wenn Ihr Parameter mehrere Ressourcentypen unterstützt, können Sie einem bestimmten Parameter mehr als eine Annotation für den Ressourcentyp hinzufügen. Verwenden Sie @AnyRes
, um anzugeben, dass der annotierte Parameter ein beliebiger Typ von R
-Ressource sein kann.
Sie können zwar @ColorRes
verwenden, um anzugeben, dass ein Parameter eine Farbressource sein soll, aber eine Farbganzzahl (im Format RRGGBB
oder AARRGGBB
) wird nicht als Farbressource erkannt. Verwenden Sie stattdessen die Annotation @ColorInt
, um anzugeben, dass ein Parameter eine Farbganzzahl sein muss. Die Build-Tools kennzeichnen falschen Code, bei dem eine Farbressourcen-ID wie android.R.color.black
anstelle einer Farbganzzahl an annotierte Methoden übergeben wird.
Thread-Annotationen
Mit Thread-Anmerkungen wird geprüft, ob eine Methode von einem bestimmten Threadtyp aufgerufen wird. Die folgenden Thread-Anmerkungen werden unterstützt:
Die Build-Tools behandeln die Annotationen @MainThread
und @UiThread
als austauschbar. Sie können also @UiThread
-Methoden aus @MainThread
-Methoden aufrufen und umgekehrt. Bei System-Apps mit mehreren Ansichten in verschiedenen Threads kann es jedoch vorkommen, dass sich ein UI-Thread vom Hauptthread unterscheidet. Daher sollten Sie Methoden, die mit der Ansichtshierarchie einer App verknüpft sind, mit @UiThread
und Methoden, die mit dem Lebenszyklus einer App verknüpft sind, mit @MainThread
annotieren.
Wenn alle Methoden in einer Klasse dieselbe Threading-Anforderung haben, können Sie der Klasse eine einzelne Thread-Annotation hinzufügen, um zu prüfen, ob alle Methoden in der Klasse vom selben Threadtyp aufgerufen werden.
Eine häufige Verwendung von Thread-Annotationen besteht darin, zu prüfen, ob Methoden oder Klassen, die mit @WorkerThread
annotiert sind, nur von einem geeigneten Hintergrundthread aufgerufen werden.
Anmerkungen zu Wertbeschränkungen
Verwenden Sie die Anmerkungen @IntRange
, @FloatRange
und @Size
, um die Werte der übergebenen Parameter zu validieren. Sowohl @IntRange
als auch @FloatRange
sind am nützlichsten, wenn sie auf Parameter angewendet werden, bei denen Nutzer wahrscheinlich den Bereich falsch angeben.
Mit der Annotation @IntRange
wird geprüft, ob ein Parameterwert vom Typ „integer“ oder „long“ innerhalb eines angegebenen Bereichs liegt. Im folgenden Beispiel wird angegeben, dass der Parameter alpha
einen Ganzzahlwert zwischen 0 und 255 enthalten muss:
Kotlin
fun setAlpha(@IntRange(from = 0, to = 255) alpha: Int) { ... }
Java
public void setAlpha(@IntRange(from=0,to=255) int alpha) { ... }
Mit der Annotation @FloatRange
wird geprüft, ob ein Parameterwert vom Typ „float“ oder „double“ innerhalb eines angegebenen Bereichs von Gleitkommawerten liegt. Im folgenden Beispiel wird angegeben, dass der Parameter alpha
einen Gleitkommawert zwischen 0,0 und 1,0 enthalten muss:
Kotlin
fun setAlpha(@FloatRange(from = 0.0, to = 1.0) alpha: Float) {...}
Java
public void setAlpha(@FloatRange(from=0.0, to=1.0) float alpha) {...}
Mit der Annotation @Size
wird die Größe einer Sammlung oder eines Arrays oder die Länge eines Strings geprüft. Mit der Anmerkung @Size
können die folgenden Eigenschaften überprüft werden:
- Mindestgröße, z. B.
@Size(min=2)
- Maximale Größe, z. B.
@Size(max=2)
- Genaue Größe, z. B.
@Size(2)
- Eine Zahl, von der die Größe ein Vielfaches sein muss, z. B.
@Size(multiple=2)
Mit @Size(min=1)
wird beispielsweise geprüft, ob eine Sammlung nicht leer ist, und mit @Size(3)
wird validiert, ob ein Array genau drei Werte enthält.
Das folgende Beispiel zeigt, dass das Array location
mindestens ein Element enthalten muss:
Kotlin
fun getLocation(button: View, @Size(min=1) location: IntArray) { button.getLocationOnScreen(location) }
Java
void getLocation(View button, @Size(min=1) int[] location) { button.getLocationOnScreen(location); }
Berechtigungsanmerkungen
Verwenden Sie die Annotation @RequiresPermission
, um die Berechtigungen des Aufrufers einer Methode zu validieren. Wenn Sie eine einzelne Berechtigung aus einer Liste gültiger Berechtigungen prüfen möchten, verwenden Sie das Attribut anyOf
. Verwenden Sie das Attribut allOf
, um eine Reihe von Berechtigungen zu prüfen. Im folgenden Beispiel wird die Methode setWallpaper()
mit einer Anmerkung versehen, um anzugeben, dass der Aufrufer der Methode die Berechtigung permission.SET_WALLPAPERS
haben muss:
Kotlin
@RequiresPermission(Manifest.permission.SET_WALLPAPER) @Throws(IOException::class) abstract fun setWallpaper(bitmap: Bitmap)
Java
@RequiresPermission(Manifest.permission.SET_WALLPAPER) public abstract void setWallpaper(Bitmap bitmap) throws IOException;
Im folgenden Beispiel muss der Aufrufer der Methode copyImageFile()
sowohl Lesezugriff auf den externen Speicher als auch Lesezugriff auf die Standortmetadaten im kopierten Bild haben:
Kotlin
@RequiresPermission(allOf = [ Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.ACCESS_MEDIA_LOCATION ]) fun copyImageFile(dest: String, source: String) { ... }
Java
@RequiresPermission(allOf = { Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.ACCESS_MEDIA_LOCATION}) public static final void copyImageFile(String dest, String source) { //... }
Für Berechtigungen für Intents platzieren Sie die Berechtigungsanforderung im Stringfeld, das den Namen der Intent-Aktion definiert:
Kotlin
@RequiresPermission(android.Manifest.permission.BLUETOOTH) const val ACTION_REQUEST_DISCOVERABLE = "android.bluetooth.adapter.action.REQUEST_DISCOVERABLE"
Java
@RequiresPermission(android.Manifest.permission.BLUETOOTH) public static final String ACTION_REQUEST_DISCOVERABLE = "android.bluetooth.adapter.action.REQUEST_DISCOVERABLE";
Bei Berechtigungen für Contentanbieter, für die separate Berechtigungen für Lese- und Schreibzugriff erforderlich sind, müssen Sie jede Berechtigungsanforderung in einer @RequiresPermission.Read
- oder @RequiresPermission.Write
-Annotation einschließen:
Kotlin
@RequiresPermission.Read(RequiresPermission(READ_HISTORY_BOOKMARKS)) @RequiresPermission.Write(RequiresPermission(WRITE_HISTORY_BOOKMARKS)) val BOOKMARKS_URI = Uri.parse("content://browser/bookmarks")
Java
@RequiresPermission.Read(@RequiresPermission(READ_HISTORY_BOOKMARKS)) @RequiresPermission.Write(@RequiresPermission(WRITE_HISTORY_BOOKMARKS)) public static final Uri BOOKMARKS_URI = Uri.parse("content://browser/bookmarks");
Indirekte Berechtigungen
Wenn eine Berechtigung vom spezifischen Wert abhängt, der für den Parameter einer Methode angegeben wird, verwenden Sie @RequiresPermission
für den Parameter selbst, ohne die spezifischen Berechtigungen aufzulisten.
Die Methode startActivity(Intent)
verwendet beispielsweise eine indirekte Berechtigung für den Intent, der an die Methode übergeben wird:
Kotlin
abstract fun startActivity(@RequiresPermission intent: Intent, bundle: Bundle?)
Java
public abstract void startActivity(@RequiresPermission Intent intent, @Nullable Bundle)
Wenn Sie indirekte Berechtigungen verwenden, führen die Build-Tools eine Datenflussanalyse durch, um zu prüfen, ob das an die Methode übergebene Argument @RequiresPermission
-Annotationen enthält. Anschließend werden alle vorhandenen Anmerkungen aus dem Parameter auf die Methode selbst angewendet. Im Beispiel startActivity(Intent)
führen Anmerkungen in der Klasse Intent
zu den resultierenden Warnungen bei ungültigen Verwendungen von startActivity(Intent)
, wenn ein Intent ohne die entsprechenden Berechtigungen an die Methode übergeben wird, wie in Abbildung 1 dargestellt.

Abbildung 1: Die Warnung, die durch eine Annotation für indirekte Berechtigungen für die Methode startActivity(Intent)
generiert wird.
Die Build-Tools generieren die Warnung für startActivity(Intent)
aus der Annotation für den entsprechenden Intent-Aktionsnamen in der Klasse Intent
:
Kotlin
@RequiresPermission(Manifest.permission.CALL_PHONE) const val ACTION_CALL = "android.intent.action.CALL"
Java
@RequiresPermission(Manifest.permission.CALL_PHONE) public static final String ACTION_CALL = "android.intent.action.CALL";
Bei Bedarf können Sie @RequiresPermission
durch @RequiresPermission.Read
oder @RequiresPermission.Write
ersetzen, wenn Sie einen Methodenparameter annotieren. Bei indirekten Berechtigungen sollte @RequiresPermission
jedoch nicht in Verbindung mit Anmerkungen zu Lese- oder Schreibberechtigungen verwendet werden.
Anmerkungen zu Rückgabewerten
Verwenden Sie die Annotation @CheckResult
, um zu prüfen, ob das Ergebnis oder der Rückgabewert einer Methode tatsächlich verwendet wird. Anstatt jede Methode, die nicht „void“ ist, mit @CheckResult
zu annotieren, sollten Sie die Annotation hinzufügen, um die Ergebnisse potenziell verwirrender Methoden zu verdeutlichen.
Neue Java-Entwickler gehen beispielsweise oft fälschlicherweise davon aus, dass <String>.trim()
Leerzeichen aus dem ursprünglichen String entfernt. Wenn Sie die Methode mit @CheckResult
annotieren, werden Verwendungen von <String>.trim()
gekennzeichnet, bei denen der Aufrufer nichts mit dem Rückgabewert der Methode unternimmt.
Im folgenden Beispiel wird die Methode checkPermissions()
annotiert, um zu prüfen, ob der Rückgabewert der Methode tatsächlich referenziert wird. Außerdem wird die Methode enforcePermission()
als Ersatz für Entwickler vorgeschlagen:
Kotlin
@CheckResult(suggest = "#enforcePermission(String,int,int,String)") abstract fun checkPermission(permission: String, pid: Int, uid: Int): Int
Java
@CheckResult(suggest="#enforcePermission(String,int,int,String)") public abstract int checkPermission(@NonNull String permission, int pid, int uid);
CallSuper-Annotationen
Verwenden Sie die Annotation @CallSuper
, um zu prüfen, ob eine überschreibende Methode die Super-Implementierung der Methode aufruft.
Im folgenden Beispiel wird die Methode onCreate()
mit Anmerkungen versehen, um sicherzustellen, dass alle überschreibenden Methodenimplementierungen super.onCreate()
aufrufen:
Kotlin
@CallSuper override fun onCreate(savedInstanceState: Bundle?) { }
Java
@CallSuper protected void onCreate(Bundle savedInstanceState) { }
Typedef-Annotationen
Mit Typedef-Anmerkungen wird geprüft, ob ein bestimmter Parameter, Rückgabewert oder ein bestimmtes Feld auf eine bestimmte Gruppe von Konstanten verweist. Außerdem wird dadurch die automatische Codevervollständigung mit den zulässigen Konstanten ermöglicht.
Verwenden Sie die Anmerkungen @IntDef
und @StringDef
, um aufgezählte Anmerkungen von Ganzzahl- und String-Sets zu erstellen, um andere Arten von Code-Referenzen zu validieren.
Typedef-Annotationen verwenden @interface
, um den neuen aufgezählten Annotationstyp zu deklarieren.
Die Annotationen @IntDef
und @StringDef
sowie @Retention
annotieren die neue Annotation und sind erforderlich, um den aufgezählten Typ zu definieren. Die Annotation @Retention(RetentionPolicy.SOURCE)
weist den Compiler an, die aufgezählten Annotationsdaten nicht in der Datei .class
zu speichern.
Im folgenden Beispiel wird gezeigt, wie Sie eine Annotation erstellen, mit der geprüft wird, ob ein als Methodenparameter übergebener Wert auf eine der definierten Konstanten verweist:
Kotlin
import androidx.annotation.IntDef //... // Define the list of accepted constants and declare the NavigationMode annotation. @Retention(AnnotationRetention.SOURCE) @IntDef(NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS) annotation class NavigationMode // Declare the constants. const val NAVIGATION_MODE_STANDARD = 0 const val NAVIGATION_MODE_LIST = 1 const val NAVIGATION_MODE_TABS = 2 abstract class ActionBar { // Decorate the target methods with the annotation. // Attach the annotation. @get:NavigationMode @setparam:NavigationMode abstract var navigationMode: Int }
Java
import androidx.annotation.IntDef; //... public abstract class ActionBar { //... // Define the list of accepted constants and declare the NavigationMode annotation. @Retention(RetentionPolicy.SOURCE) @IntDef({NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS}) 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); }
Wenn Sie diesen Code erstellen, wird eine Warnung generiert, wenn der Parameter mode
nicht auf eine der definierten Konstanten (NAVIGATION_MODE_STANDARD
, NAVIGATION_MODE_LIST
oder NAVIGATION_MODE_TABS
) verweist.
Kombinieren Sie @IntDef
und @IntRange
, um anzugeben, dass eine Ganzzahl entweder eine bestimmte Gruppe von Konstanten oder ein Wert in einem Bereich sein kann.
Kombinieren von Konstanten mit Flags aktivieren
Wenn Nutzer die zulässigen Konstanten mit einem Flag (z. B. |
, &
, ^
usw.) kombinieren können, können Sie eine Anmerkung mit einem flag
-Attribut definieren, um zu prüfen, ob ein Parameter oder Rückgabewert auf ein gültiges Muster verweist.
Im folgenden Beispiel wird die Annotation DisplayOptions
mit einer Liste gültiger DISPLAY_
-Konstanten erstellt:
Kotlin
import androidx.annotation.IntDef ... @IntDef(flag = true, value = [ DISPLAY_USE_LOGO, DISPLAY_SHOW_HOME, DISPLAY_HOME_AS_UP, DISPLAY_SHOW_TITLE, DISPLAY_SHOW_CUSTOM ]) @Retention(AnnotationRetention.SOURCE) annotation class DisplayOptions ...
Java
import androidx.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 {} ...
Wenn Sie Code mit einem Anmerkungsflag erstellen, wird eine Warnung generiert, wenn der dekorierte Parameter oder Rückgabewert nicht auf ein gültiges Muster verweist.
Annotation beibehalten
Die Annotation @Keep
sorgt dafür, dass eine annotierte Klasse oder Methode nicht entfernt wird, wenn der Code zur Build-Zeit minimiert wird. Diese Annotation wird in der Regel Methoden und Klassen hinzugefügt, auf die über Reflection zugegriffen wird, um zu verhindern, dass der Compiler den Code als nicht verwendet behandelt.
Achtung : Die Klassen und Methoden, die Sie mit @Keep
annotieren, sind immer im APK Ihrer App enthalten, auch wenn Sie in der Logik Ihrer App nie darauf verweisen.
Um die Größe Ihrer App gering zu halten, sollten Sie überlegen, ob es notwendig ist, jede @Keep
-Annotation in Ihrer App beizubehalten. Wenn Sie Reflection verwenden, um auf eine annotierte Klasse oder Methode zuzugreifen, verwenden Sie in Ihren ProGuard-Regeln eine
-if
-Bedingung, in der Sie die Klasse angeben, die die Reflection-Aufrufe ausführt.
Weitere Informationen zum Minimieren von Code und zum Festlegen, welcher Code nicht entfernt werden soll, finden Sie unter App verkleinern, verschleiern und optimieren.
Vermerke zur Code-Sichtbarkeit
Verwenden Sie die folgenden Anmerkungen, um die Sichtbarkeit bestimmter Codeabschnitte wie Methoden, Klassen, Felder oder Pakete anzugeben.
Code für Tests sichtbar machen
Die Annotation @VisibleForTesting
gibt an, dass eine annotierte Methode sichtbarer ist, als normalerweise erforderlich, um die Methode testbar zu machen. Diese Annotation hat ein optionales otherwise
-Argument, mit dem Sie festlegen können, welche Sichtbarkeit die Methode hätte, wenn sie nicht für Tests sichtbar gemacht werden müsste. Lint verwendet das Argument otherwise
, um die beabsichtigte Sichtbarkeit zu erzwingen.
Im folgenden Beispiel ist myMethod()
normalerweise private
, aber für Tests ist es package-private
. Mit der Kennzeichnung VisibleForTesting.PRIVATE
zeigt Lint eine Meldung an, wenn diese Methode außerhalb des durch den private
-Zugriff zulässigen Kontexts aufgerufen wird, z. B. aus einer anderen Kompiliereinheit.
Kotlin
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) fun myMethod() { ... }
Java
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) void myMethod() { ... }
Sie können auch @VisibleForTesting(otherwise = VisibleForTesting.NONE)
angeben, um anzugeben, dass eine Methode nur zum Testen vorhanden ist. Dieses Formular entspricht der Verwendung von @RestrictTo(TESTS)
. Beide führen denselben Lint-Check aus.
API einschränken
Die Annotation @RestrictTo
gibt an, dass der Zugriff auf die annotierte API (Paket, Klasse oder Methode) wie folgt eingeschränkt ist:
Unterklassen
Verwenden Sie das Annotationsformular @RestrictTo(RestrictTo.Scope.SUBCLASSES)
, um den API-Zugriff auf Unterklassen zu beschränken.
Nur Klassen, die die annotierte Klasse erweitern, können auf diese API zugreifen. Der Java-Modifikator protected
ist nicht restriktiv genug, da er den Zugriff von nicht verwandten Klassen innerhalb desselben Pakets zulässt. Es gibt auch Fälle, in denen Sie eine Methode public
für zukünftige Flexibilität beibehalten möchten, da Sie eine zuvor protected
und überschriebene Methode public
nie erstellen können. Sie möchten jedoch einen Hinweis darauf geben, dass die Klasse nur für die Verwendung innerhalb der Klasse oder von Unterklassen vorgesehen ist.
Bibliotheken
Verwenden Sie das Annotationsformular @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
, um den API-Zugriff auf Ihre Bibliotheken zu beschränken.
Nur Ihr Bibliothekscode kann auf die annotierte API zugreifen. So können Sie Ihren Code nicht nur in einer beliebigen Pakethierarchie organisieren, sondern auch für eine Gruppe verwandter Bibliotheken freigeben. Diese Option ist bereits für die Jetpack-Bibliotheken verfügbar, die viel Implementierungscode enthalten, der nicht für die externe Verwendung vorgesehen ist, aber public
sein muss, um ihn für die verschiedenen ergänzenden Jetpack-Bibliotheken freizugeben.
Testen
Verwenden Sie das Anmerkungsformular @RestrictTo(RestrictTo.Scope.TESTS)
, um zu verhindern, dass andere Entwickler auf Ihre Test-APIs zugreifen.
Nur Testcode kann auf die annotierte API zugreifen. So wird verhindert, dass andere Entwickler APIs für die Entwicklung verwenden, die Sie nur für Testzwecke vorgesehen haben.