Ulepsz inspekcję kodu za pomocą adnotacji

Narzędzia do inspekcji kodu, takie jak Lint, pomogą Ci znaleźć i ulepszać kod, ale narzędzia inspekcyjne są w stanie wywnioskować tylko wiele. identyfikatory zasobów Androida, np. int do identyfikacji ciągów znaków, grafik, kolorów i innych typów zasobów, więc narzędzia do inspekcji nie będą w stanie określić, czy określono zasób ciągu znaków, w którym należy określono kolor. Oznacza to, że aplikacja może renderować się nieprawidłowo lub w ogóle się nie uruchomić, nawet w przypadku inspekcji kodu.

Adnotacje umożliwiają podawanie wskazówek do narzędzi do inspekcji kodu, takich jak lint, które pomagają je wykrywać subtelne problemy z kodem. Adnotacje są dodawane jako tagi metadanych dołączane do zmiennych, i zwracaj wartości, by sprawdzać zwracane wartości metody, przekazywane parametry, zmienne lokalne i pól. W przypadku narzędzi do sprawdzania kodu adnotacje mogą pomóc w wykrywaniu problemów takich jak: wyjątki wskaźnika null i konflikty typów zasobów.

Android obsługuje różne adnotacje w formatach Biblioteka adnotacji Jetpack. Dostęp do biblioteki możesz uzyskać w androidx.annotation pakietu SDK.

Uwaga: jeśli moduł jest zależny od procesora adnotacji, musisz użyć konfiguracji zależności kapt lub ksp dla Kotlin lub konfigurację zależności annotationProcessor w Javie, aby dodać ten element zależności.

Dodawanie adnotacji do projektu

Aby włączyć adnotacje w projekcie, dodaj androidx.annotation:annotation zależnie od biblioteki lub aplikacji. Wszystkie dodane adnotacje są sprawdzane podczas uruchamiania kodu inspekcja lub zadanie lint.

Dodaj zależność biblioteki Jetpack Adnotacje

Biblioteka adnotacji Jetpack została opublikowana Repozytorium Google Maven. Aby dodać do projektu bibliotekę Adnotacji Jetpack, umieść w nim te elementy: w bloku dependencies build.gradle lub Plik build.gradle.kts:

Kotlin

dependencies {
    implementation("androidx.annotation:annotation:1.8.2")
}

Odlotowe

dependencies {
    implementation 'androidx.annotation:annotation:1.8.2'
}
Następnie na pasku narzędzi lub w powiadomieniu o synchronizacji, które się pojawią, kliknij Synchronizuj teraz.

Jeśli używasz adnotacji we własnym module biblioteki, są one dołączone do modułu Artefakt Android Archive (AAR) w formacie XML w pliku annotations.zip. Dodanie Zależność androidx.annotation nie powoduje powstania zależności u żadnych użytkowników podrzędnych Twojej biblioteki.

Uwaga: jeśli używasz innych bibliotek Jetpack, być może nie musisz dodawać zależności androidx.annotation. Wiele innych Biblioteki Jetpack zależą od biblioteki adnotacji. Być może masz już dostęp do adnotacji.

Pełną listę adnotacji znajdujących się w repozytorium Jetpack znajdziesz w Biblioteka adnotacji w Jetpack lub skorzystaj z funkcji autouzupełniania, aby wyświetlić opcje dostępne dla zapytania import androidx.annotation. – instrukcja.

Przeprowadzanie inspekcji kodu

Aby rozpocząć kontrolę kodu w Android Studio, która obejmuje weryfikację adnotacji i automatycznego sprawdzania lintowania, wybierz Analiza > Sprawdź kod z tagu . Android Studio wyświetla komunikaty o konfliktach, aby wskazać potencjalne problemy z kodem koliduje z adnotacjami i podpowiada możliwe rozwiązania.

Możesz też wymusić stosowanie adnotacji, uruchamiając lint przy użyciu wiersza poleceń. Może to być przydatne przy zgłaszaniu problemów z serwerem ciągłej integracji, zadanie lint nie wymusza wartości null adnotacje (opisane w następnej sekcji); robi to tylko Android Studio. Więcej informacje o włączaniu i uruchamianiu lint inspekcje można znaleźć w artykule Udoskonalanie kodu za pomocą Lenta. weryfikacji.

Chociaż konflikty adnotacji generują ostrzeżenia, nie uniemożliwiają one aplikacji z kompilowania.

Adnotacje o wartości null

Adnotacje null mogą być przydatne w kodzie Java, gdy trzeba ustalić, czy wartości mogą mieć wartość null. Są one mniej przydatne w kodzie Kotlin, ponieważ Kotlin ma wbudowane reguły dopuszczania wartości null, które są egzekwowane czas kompilowania.

Dodaj: @Nullable i @NonNull adnotacje , aby sprawdzić wartość null danej zmiennej, parametru lub zwróconej wartości. @Nullable wskazuje zmienną, parametr lub wartość zwracaną, która może mieć wartość null. @NonNull oznacza zmienną, parametr lub wartość zwracaną, które nie mogą być puste.

Jeśli na przykład zmienna lokalna zawierająca wartość null jest przekazywana jako parametr do metody z adnotacją @NonNull dołączoną do tego parametru, utworzenie kodu spowoduje wygenerowanie oznaczający konflikt niepusty. Ponadto próba odwoływania się do wyniku funkcji metoda oznaczona przez @Nullable bez wcześniejszego sprawdzenia, czy wynik ma wartość null, ostrzeżenie o braku wartości. Używaj tylko wartości @Nullable dla zwracanej wartości metody jeśli każde użycie metody musi być wyraźnie zaznaczone na wartość null.

Poniższy przykład pokazuje, jak w praktyce działa dopuszczanie wartości null. Przykładowy kod Kotlin nie wykorzystuje adnotacji @NonNull, ponieważ jest ona automatycznie dodawana do wygenerowanego kodu bajtowego gdy określony jest typ niedopuszczający wartości null. Przykład w Javie wykorzystuje adnotację @NonNull w parametrach context i attrs, aby sprawdzić, czy przekazywane wartości parametrów nie mają wartości null. Sprawdza też, czy sama metoda onCreateView() nie zwraca wartości null:

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) {
      ...
      }
...

Analiza wartości null

Android Studio obsługuje przeprowadzanie analizy wartości null w celu automatycznego wnioskowania i wstaw w kodzie adnotacje o braku wartości. Skanowanie pod kątem możliwości null kontrakty w hierarchii metod w kodzie do wykrywania:

  • Metody wywołań, które mogą zwracać wartość null.
  • Metody, które nie powinny zwracać wartości null.
  • zmiennych, takich jak pola, zmienne lokalne i parametry, które można wartość null.
  • zmiennych, takich jak pola, zmienne lokalne i parametry, które nie mogą mają wartość null.

Następnie analiza automatycznie wstawia odpowiednie adnotacje o wartości null w polu wykryte lokalizacje.

Aby w Android Studio przeprowadzić analizę wartości null, wybierz Analizuj > Wniosek o nullity. Android Studio wstawia adnotacje @Nullable i @NonNull z Androida wykryte lokalizacje w kodzie. Po przeprowadzeniu analizy null warto zweryfikować wstrzykniętych adnotacji.

Uwaga: podczas dodawania adnotacji o stanie null autouzupełnianie może zasugeruj IntelliJ @Nullable i @NotNull adnotacji zamiast pustych adnotacji Androida i może automatycznie zaimportować odpowiednią bibliotekę. Jednak Android Studio Narzędzie do sprawdzania lint wyświetla tylko puste adnotacje Androida. Podczas weryfikacji sprawdź, czy Twój projekt używa pustych adnotacji Androida, dzięki czemu Narzędzie do sprawdzania lint może odpowiednio powiadomić Cię podczas inspekcji kodu.

Adnotacje dotyczące zasobów

Weryfikowanie typów zasobów może być przydatne, ponieważ odwołania Androida do zasobów, takich jak zasoby drawable i string, są przekazywane jako liczby całkowite.

Kod, który oczekuje, że parametr odwoły się do określonego typu zasobu, np. String, może zostać przekazana do oczekiwanego typu pliku referencyjnego int, ale w rzeczywistości odwołuje się do innego typu zasobu, na przykład R.string.

Na przykład dodaj adnotacje @StringRes do sprawdź, czy parametr zasobu zawiera odwołanie do R.string, jak poniżej:

Kotlin

abstract fun setTitle(@StringRes resId: Int)

Java

public abstract void setTitle(@StringRes int resId)

Podczas inspekcji kodu adnotacja generuje ostrzeżenie, jeśli odwołanie do R.string nie jest przekazywany w parametrze.

Adnotacje dla innych typów zasobów, takich jak @DrawableRes, @DimenRes, @ColorRes i @InterpolatorRes, mogą być dodane za pomocą tego samego formatu adnotacji i są uruchamiane podczas inspekcji kodu.

Jeśli Twój parametr obsługuje wiele typów zasobów, do każdego z nich możesz dodać . Użyj formatu: @AnyRes wskazuje, że parametr z adnotacjami może być dowolnym typem zasobu R.

Możesz jednak użyć właściwości @ColorRes, aby określić, że powinien być zasobem koloru, liczbą całkowitą koloru (w RRGGBB lub format AARRGGBB) nie jest rozpoznawany jako zasób koloru. Zamiast tego używaj adnotacji @ColorInt, aby: wskazują, że parametr musi być liczbą całkowitą koloru. Narzędzia do kompilacji oznaczą nieprawidłowy kod, który przekazuje identyfikator zasobu koloru, taki jak android.R.color.black, a nie liczbę całkowitą koloru, na metody z adnotacjami.

Adnotacje w wątkach

Adnotacje wątków sprawdzają, czy metoda jest wywoływana z określonego typu wątek. Następujący wątek Obsługiwane są adnotacje:

Narzędzia do kompilacji traktują @MainThread oraz Adnotacje @UiThread jako wymienne, możesz więc wywołać funkcję @UiThread z metod @MainThread i odwrotnie. Istnieje jednak możliwość w przypadku aplikacji systemowych z wieloma widokami, w różnych wątkach. Dlatego należy dodawać adnotacje do metod powiązanych z hierarchią widoków aplikacji. za pomocą funkcji @UiThread i dodawać adnotacje tylko do metod związanych z cyklem życia aplikacji za pomocą polecenia @MainThread

Jeśli wszystkie metody w zajęciach mają takie same wymagania dotyczące wątków, możesz dodać 1 wątek. adnotacji do klasy w celu sprawdzenia, czy wszystkie metody w klasie są wywoływane z tego samego typu w wątku.

Typowym zastosowaniem adnotacji w wątku jest sprawdzenie, czy metody lub klasy z adnotacjami Funkcje @WorkerThread są wywoływane wyłącznie z odpowiedniego wątku w tle.

Adnotacje ograniczenia wartości

Korzystaj z funkcji @IntRange, @FloatRange i @Size adnotacji do sprawdzać wartości przekazywanych parametrów. Zarówno @IntRange, jak i @FloatRange są najbardziej przydatne w przypadku parametrów, w których użytkownicy mogą pomylić zakres.

Adnotacja @IntRange sprawdza, czy liczba całkowita lub długi parametr wartość mieści się w określonym zakresie. W poniższym przykładzie widać, że alpha musi zawierać liczbę całkowitą od 0 do 255:

Kotlin

fun setAlpha(@IntRange(from = 0, to = 255) alpha: Int) { ... }

Java

public void setAlpha(@IntRange(from=0,to=255) int alpha) { ... }

Adnotacja @FloatRange sprawdza, czy jest to parametr zmiennoprzecinkowy czy zmiennoprzecinkowy. mieści się w określonym zakresie wartości zmiennoprzecinkowych. W poniższym przykładzie Parametr alpha musi zawierać wartość zmiennoprzecinkową od 0,0 do 1,0:

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) {...}

Adnotacja @Size sprawdza rozmiar kolekcji lub lub długość ciągu znaków. Adnotacja @Size może służyć do weryfikacji mają następujące cechy:

  • Minimalny rozmiar, np. @Size(min=2)
  • Maksymalny rozmiar, np. @Size(max=2)
  • Dokładny rozmiar, np. @Size(2)
  • Liczba, której rozmiar musi być wielokrotnością wartości, np. @Size(multiple=2)

Na przykład: @Size(min=1) sprawdza, czy kolekcja nie jest pusta, a @Size(3) sprawdza, czy tablica zawiera dokładnie 3 wartości.

W poniższym przykładzie Tablica location musi zawierać co najmniej 1 element:

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);
}

Adnotacje dotyczące uprawnień

Użyj funkcji @RequiresPermission adnotacji w celu sprawdzenia uprawnień obiektu wywołującego metodę. Sprawdzanie pojedynczego uprawnienia z listy prawidłowych uprawnień, użyj atrybutu anyOf. Aby sprawdzić zestaw uprawnień, użyj atrybutu allOf. W poniższym przykładzie adnotacje setWallpaper() wskazuje, że element wywołujący metody musi mieć parametr Uprawnienie permission.SET_WALLPAPERS:

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;

Ten przykład wymaga wywołania metody copyImageFile() zarówno z dostępem do odczytu pamięci zewnętrznej, jak i z dostępem do lokalizacji. metadanych w kopiowanym obrazie:

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) {
    //...
}

W przypadku uprawnień do intencji umieść wymagane uprawnienia w polu ciągu, które określa nazwa działania intencji:

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

W przypadku uprawnień dostawców treści, którzy potrzebują osobnych uprawnień do odczytu i zapisu dostępu, umieść wszystkie wymagania dotyczące uprawnień w elemencie @RequiresPermission.Read lub @RequiresPermission.Write adnotacja:

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");

Uprawnienia pośrednie

Jeśli uprawnienie zależy od konkretnej wartości dostarczonej parametrowi metody, użyj funkcji @RequiresPermission w samym parametrze, nie podając żadnych konkretnych uprawnień. Na przykład startActivity(Intent) używa pośredniego uprawnienia do intencji przekazywanej do metody:

Kotlin

abstract fun startActivity(@RequiresPermission intent: Intent, bundle: Bundle?)

Java

public abstract void startActivity(@RequiresPermission Intent intent, @Nullable Bundle)

Gdy korzystasz z uprawnień pośrednich, narzędzia do kompilacji przeprowadzają analizę przepływu danych, aby sprawdzić, czy argument przekazany do metody ma wszystkie adnotacje @RequiresPermission. Następnie wymuszać istniejące adnotacje z parametru w samej metodzie. W W przypadku przykładu startActivity(Intent) adnotacje w klasie Intent powodują wyświetlenie ostrzeżeń w przypadku nieprawidłowego użycia atrybutu startActivity(Intent) w przypadku intencji bez odpowiedniej są przekazywane do metody, jak widać na rysunku 1.

Rysunek 1. Ostrzeżenie wygenerowane w wyniku pośredniego w adnotacji o uprawnieniach w metodzie startActivity(Intent).

Narzędzia do kompilacji generują ostrzeżenie startActivity(Intent) na podstawie adnotacji obok odpowiedniej nazwy działania intencji w klasie 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";

W razie potrzeby możesz zastąpić @RequiresPermission @RequiresPermission.Read lub @RequiresPermission.Write podczas dodawania adnotacji parametru metody. Jednak w przypadku uprawnień pośrednich @RequiresPermission powinien nie można używać w połączeniu z adnotacjami uprawnień do odczytu ani zapisu.

Adnotacje wartości zwracanych

Używaj adnotacji @CheckResult, aby: w celu sprawdzenia, czy wynik lub wartość zwracana metody faktycznie jest używana. Zamiast dodawać adnotacje do każdego niepustej metody za pomocą funkcji @CheckResult, dodaj adnotację, aby objaśnić wyniki metod, które mogą wprowadzać w błąd.

Na przykład nowi programiści Java często sądzą, że <String>.trim() usuwa odstępy z oryginalnego ciągu. Dodaje adnotacje metoda z flagami @CheckResult używa <String>.trim() gdzie element wywołujący nie robi nic z wartością zwracaną metody.

W przykładzie poniżej podano adnotacje w polu checkPermissions() do sprawdzenia, czy zwracana wartość metody jest rzeczywiście przywoływanych. enforcePermission() ma też nazwę jako metodę sugerowaną deweloperowi jako zamiennik:

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

Adnotacje CallSuper

Używaj adnotacji @CallSuper, aby: sprawdzić, czy metoda zastępowania wywołuje superimplementację.

Poniżej adnotacja metody onCreate(), aby zapewnić, że dowolna metoda zastępowania implementacje wywołują super.onCreate():

Kotlin

@CallSuper
override fun onCreate(savedInstanceState: Bundle?) {
}

Java

@CallSuper
protected void onCreate(Bundle savedInstanceState) {
}

Adnotacje Typedef

Adnotacje Typedef sprawdzają, czy określony parametr, zwracana wartość lub pola odwołują się do konkretnego zestawu stałych. Umożliwiają też automatyczne uzupełnianie kodu że są dozwolone stałe.

Korzystaj z dokumentów @IntDef oraz @StringDef adnotacje do tworzenia wyliczanych adnotacji liczb całkowitych i zbiorów ciągów w celu weryfikacji innych typy odwołań do kodu.

Adnotacje Typedef korzystają z pola @interface do deklarowania nowego wyliczanego typu adnotacji. Adnotacje @IntDef i @StringDef wraz z @Retention, dodaj adnotacje do nowej adnotacji i są niezbędne do zdefiniowania wyliczany typ. Adnotacja @Retention(RetentionPolicy.SOURCE) informuje kompilator aby nie przechowywać wyliczonych danych adnotacji w pliku .class.

Przykład poniżej pokazuje, jak utworzyć adnotację, która sprawdza, czy wartość została przekazana , bo parametr metody odwołuje się do jednej ze zdefiniowanych stałych:

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);
}

Gdy utworzysz ten kod, zostanie wygenerowane ostrzeżenie, jeśli parametr mode nie będzie odwołują się do jednej ze zdefiniowanych stałych (NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST lub NAVIGATION_MODE_TABS).

Połącz atrybuty @IntDef i @IntRange, aby wskazać, że Liczba całkowita może być albo określonym zbiorem stałych albo wartością z zakresu.

Włącz łączenie stałych z flagami

Jeśli użytkownicy mogą połączyć dozwolone stałe z flagą (np. |, &, ^ itd.), możesz zdefiniować adnotację za pomocą flag, aby sprawdzić, czy parametr lub zwracana wartość odwołuje się do prawidłowego wzorca.

Poniższy przykład tworzy adnotację DisplayOptions z listą prawidłowych Stałe DISPLAY_:

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

...

W przypadku tworzenia kodu przy użyciu flagi adnotacji generowane jest ostrzeżenie, jeśli parametr dekoracji lub zwracana wartość nie odnosi się do prawidłowego wzorca.

Zachowaj adnotację

@Keep pozwala uniknąć usunięcia klasy lub metody z adnotacjami, gdy kod jest zmniejszany w momencie kompilacji. Zwykle są to adnotacje do metod i klas, do których dostęp uzyskuje się przez odbicie, aby uniemożliwić kompilatorowi traktując kod jako nieużywany.

Uwaga: zajęcia i metody, które dodajesz do adnotacji rozszerzenie @Keep zawsze pojawia się w pakiecie APK aplikacji, nawet jeśli nigdy które odnoszą się do tych klas i metod w ramach logiki aplikacji.

Aby aplikacja była mały, zastanów się, czy nie trzeba jej używać każda adnotacja @Keep w aplikacji. Jeśli używasz odczuć, uzyskać dostęp do klasy lub metody z adnotacjami, użyj funkcji -if warunkowo w regułach ProGuard, który określa klasę który wywołuje odczucia.

Aby uzyskać więcej informacji o tym, jak zmniejszyć kod i określić, który kod nie ma być usuwany, Więcej informacji znajdziesz w artykule Zmniejszanie, zaciemnianie i optymalizowanie aplikacji.

Adnotacje widoczności kodu

Użyj poniższych adnotacji, aby wskazać widoczność określonych części kodu, takich jak metod, klas, pól czy pakietów.

Udostępnij kod do testowania

@VisibleForTesting wskazuje, że metoda z adnotacjami jest bardziej widoczna niż zwykle które można przetestować. Ta adnotacja ma opcjonalny argument otherwise, który umożliwia określić widoczność metody, gdyby nie potrzeba jej wyświetlenia do testów. Lint używa argumentu otherwise do egzekwowania zamierzonej widoczności.

W poniższym przykładzie myMethod() to zwykle private, ale jest to package-private na potrzeby testów. Dzięki VisibleForTesting.PRIVATE , lint wyświetli komunikat, jeśli ta metoda zostanie wywołana spoza kontekstu dozwolonego przez dostęp do private, np. z innej jednostki kompilacji.

Kotlin

@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
fun myMethod() {
    ...
}

Java

@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
void myMethod() { ... }

Możesz też określić @VisibleForTesting(otherwise = VisibleForTesting.NONE) , aby wskazać, że dana metoda jest przeznaczona wyłącznie do testowania. Ten formularz jest taki sam jak przy użyciu @RestrictTo(TESTS) Oba wykonują te same czynności lintowania.

Ograniczanie interfejsu API

@RestrictTo wskazuje, że dostęp do interfejsu API (pakietu, klasy lub metody) jest ograniczony, w następujący sposób:

Podklasy

Użyj formularza adnotacji @RestrictTo(RestrictTo.Scope.SUBCLASSES), aby ograniczyć Dostęp przez interfejs API tylko do podklas.

Dostęp do tego interfejsu API mają tylko klasy, które rozszerzają tę z adnotacją. Jawa Modyfikator protected nie jest wystarczająco restrykcyjny, ponieważ umożliwia dostęp z niepowiązanych klas w tym samym pakiecie. Może się też zdarzyć, że nie będziesz chcieć public, aby zapewnić elastyczność, ponieważ nigdy nie można protected i zastąpiono metodę public, ale chcesz podać wskazówkę, że klasa jest przeznaczona do użycia w ramach klasy lub tylko w podklasach.

Biblioteki

Użyj formularza adnotacji @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX), aby: ogranicz dostęp API tylko do swoich bibliotek.

Dostęp do interfejsu API z adnotacjami ma tylko kod Twojej biblioteki. Dzięki temu nie tylko uporządkujesz kod w dowolnej hierarchii pakietów, ale także kod w grupie powiązanych bibliotek. Ta opcja jest już dostępna dla jetpacka które zawierają dużą ilość kodu implementacji, który nie jest przeznaczony do użytku zewnętrznego, musi być public, aby udostępnić go w różnych uzupełniających bibliotekach Jetpack.

Testowanie

Użyj formularza adnotacji @RestrictTo(RestrictTo.Scope.TESTS), aby zapobiec innym dostęp do interfejsów API możliwości testowania.

Dostęp do interfejsu API z adnotacjami ma tylko kod testowy. Uniemożliwia to innym deweloperom nie możesz używać interfejsów API do programowania i których chcesz używać tylko do testów.