2017-08-20 15 views
11

Używałem klasy setId z klasy View. Według tej metodyObsługa adnotacji Android @IdRes

public void setId(@IdRes int id) // This will accept resource id 

Kiedy próbowałem użyć tej metody z jakimś wbudowaną wartość int (powiedzmy 100), to metoda zacząć rzucać poprawnego ostrzeżenie których się oczekuje

actionButton.setId(100); 

Oczekiwany zasób typu id.

Ale kiedy przekonwertowałem tę zakodowaną wartość na metodę i nigdy nie zdefiniowałem, że ta metoda zwróci @IdRes, Ostrzeżenie milknie.

private int getViewId() { 
     return 100; 
    } 

Wywołanie metody, aby ustawić identyfikator.

actionButton.setId(getViewId()); 

Czy obie wersje nie są takie same. Zakodowane na sztywno int i int powrócić z tej metody. Dlaczego w jednym przypadku ostrzeżenie o metodzie rzucania, a w innym milczy.

Dla dobra spróbowałem z StringRes, ale otrzymuję ostrzeżenie w obu przypadkach.

private void setMyString(@StringRes int resourceString) {} 

Ostrzeżenie zarówno poniżej futerały-

setMyString(1); 
    setMyString(getStringId()); getStringId returns int value 
+0

Myślę, że adnotacja @IdRes wymusza użycie identyfikatora zasobu zamiast literału. Identyfikator zasobu może być przypisany do zmiennej – Inducesmile

+0

Tak, zgadzam się @Inducesmile, ale w przypadku StringRes, nigdy nie generuje ostrzeżenia w obu przypadkach – Rahul

+0

Czy używasz linek lub używasz wbudowanego analizatora przepływu danych w Android Studio (IntelliJ IDEA)? – laalto

Odpowiedz

2

To tylko Lint ostrzeżenie ponieważ metoda oczekuje się od zmiennej klasy R.id.

Odnośnie przypadku wartości zwróconej z metody, Lint nie sprawdza, czy funkcja zwraca zwartą liczbę całkowitą czy rzeczywisty identyfikator.

z dokumentacji @IdRes to stany:

oznacza, że ​​wartość parametr powrotu całkowitą, pola lub sposób oczekiwano referencja identyfikator zasobów (np android.R.id.copy).

Również adnotacja istnieje w kodzie źródłowym do dokumentacji. Po skompilowaniu kodu adnotacja zostanie usunięta.

+1

To nie jest przypadek, próbowałem z StringRes i jaka metoda zwraca na pewno ma znaczenie. Sprawdź moje zaktualizowane pytanie. – Rahul

+0

Cóż, wygląda na to, że @StringRes oczekuje również, że instrukcja powrotu z Mehtod będzie z klasy "R.string". Ale znowu, tylko ostrzeżenie! –

+0

Tak, zgadzam się z tobą, że Nabin jest ostrzeżeniem dla lint, ale obecnie próbuję zrozumieć logikę za tym. Dlaczego StringRes rzuca błąd, a IdRes nie jest. Doceniam twoją pomoc. – Rahul

0

W jednym przypadku (@IdRes) wywołujesz metodę z API (View.setId()), , podczas gdy w drugim wywołujesz metodę we własnym kodzie. Również getViewId() nie ma adnotacji, więc nie jest oczywiste z podpisem jaki rodzaj int powraca.

z następujących metod:

private int getUndefinedRes() { 
    ... 
} 

private @IdRes int getIdRes() { 
    ... 
} 

private @StringRes int getStringRes() { 
    ... 
} 

private void setMyString(@StringRes int resourceString) { 
} 

private void setMyId(@IdRes int resourceId) { 
} 

rezultaty szarpie i kontrolne są (jak Android Studio 2.3.3):

// API method with definitely wrong value (constant) 
    // --> ERROR 
    new View(context).setId(100); 
    new TextView(context).setText(100); 

    // API method with definitely wrong value (from method declaration) 
    // --> ERROR 
    new View(context).setId(getStringRes()); 
    new TextView(context).setText(getIdRes()); 

    // API method with potentially wrong value 
    // --> ok 
    new View(context).setId(getUndefinedRes()); 
    new TextView(context).setText(getUndefinedRes()); 

    // own method with potentially wrong value 
    // --> ERROR 
    setMyString(getUndefinedRes()); 
    setMyId(getUndefinedRes()); 

Wygląda na to, że lint patrzy tylko na sygnaturę metody.

Jest także łagodniejszy, gdy wywołuje się metodę API: pokazuje błąd tylko wtedy, gdy jest oczywiste, że robi się coś nie tak. Myślę, że to dlatego, że w przeciwnym razie zmusiłbym wszystkich do dodania wielu adnotacji.

Z drugiej strony, po dodaniu adnotacji do kodu, użytkownik decyduje się na dodatkowy poziom ważności.

+0

Nie Nie przesłoniłem żadnej metody setId(), używam metody setId opcji View only. Przypadek, o którym wspominałeś w końcu -> setMyId (getUndefinedRes()); // ta metoda nie rzuca żadnego błędu, który jest moim zmartwieniem. – Rahul

+0

Myślę, że w obu przypadkach (int lub string) nie ma to nic wspólnego z przesłonięciem, ale czy wywołuje metodę z API Android lub z własnego kodu. – bwt

+0

bwt, dziękuję za patrzenie w to, ale nie wzywam żadnej metody z Api. Obie metody są zapisywane w moim pliku java – Rahul

Powiązane problemy