Co jest lepsze: @SuppressLint czy @TargetApi?

100

Mam problemy w mojej aplikacji dotyczące StrictModei dodałem fragment kodu, który zasadniczo wyłącza rozszerzenie StrictModeHelper. Jednak Lint narzeka setThreadPolicy()teraz i proponuje albo dodać

@SuppressLint 'NewApi'

lub

@TargetApi(Build.VERSION_CODES.GINGERBREAD)

do onCreate()zdarzenia widoku.

Która metoda jest preferowana ... czy w zasadzie robią to samo?

bogaty
źródło

Odpowiedzi:

176

Mam problemy w mojej aplikacji dotyczące StrictMode i dodałem fragment kodu, który zasadniczo wyłącza StrictModeHelper

Napraw błąd sieci.

Która metoda jest preferowana ... czy w zasadzie robią to samo?

@TargetApii @SuppressLintmają ten sam podstawowy efekt: tłumią błąd Lint.

Różnica polega na tym @TargetApi, że deklarujesz za pomocą parametru poziom interfejsu API, do którego adresujesz swój kod, dzięki czemu błąd może pojawić się ponownie, jeśli później zmodyfikujesz metodę, aby spróbować odwołać się do czegoś nowszego niż cytowany poziom API @TargetApi.

Załóżmy na przykład, że zamiast blokować StrictModeskargi dotyczące błędu sieciowego, próbujesz obejść problem AsyncTaskserializacji w nowszych wersjach Androida. W swoim kodzie masz metodę taką jak ta, która umożliwia włączenie puli wątków na nowszych urządzeniach i użycie domyślnego zachowania wielowątkowego na starszych urządzeniach:

  @TargetApi(11)
  static public <T> void executeAsyncTask(AsyncTask<T, ?, ?> task,
                                          T... params) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
      task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);
    }
    else {
      task.execute(params);
    }
  }

Mając @TargetApi(11)oznacza, że jeśli Lint wykryje, że używam czegoś nowszego niż mój android:minSdkVersion, ale do API Level 11, Lint nie będzie narzekać. W tym przypadku to działa. Jeśli jednak zmodyfikowałem tę metodę, aby odwołać się do czegoś, co nie zostało dodane do poziomu API 14, to błąd Lint pojawi się ponownie, ponieważ moja @TargetApi(11)adnotacja mówi, że naprawiłem kod do pracy tylko na poziomie API 11 i niższym powyżej, a nie Poziom API 14 i niższy powyżej.

Używając @SuppressLint('NewApi'), straciłbym błąd Lint dla dowolnego poziomu interfejsu API, niezależnie od tego, do czego odwołuje się mój kod i do czego mój kod jest skonfigurowany.

Dlatego @TargetApijest to preferowana adnotacja, ponieważ pozwala powiedzieć narzędziom do budowania „OK, rozwiązałem tę kategorię problemów” w bardziej szczegółowy sposób.

CommonsWare
źródło
Zdaję sobie sprawę, że preferowane byłoby użycie podejścia asynchronicznego, tylko w moim konkretnym przypadku będę trzymać się obejścia. Dziękuję za to szczegółowe i bardzo zrozumiałe wyjaśnienie - i przy tej okazji dziękuję również za bardzo pomocne strony internetowe, które bardzo pomogły mi zrozumieć niektóre koncepcje programowania na Androida! R.
richey
9
@richey: „tylko w moim przypadku będę się trzymał obejścia” - to nie jest dobry pomysł. Urządzenia mobilne są mobilne. Połączenia sieciowe są raczej niestabilne i mogą zająć znacznie więcej czasu w różnych okolicznościach (np. Słaby sygnał). Wykonywanie operacji we / wy sieci w głównym wątku aplikacji oznacza, że ​​aplikacja będzie losowo zawieszać się z błędem ANR w terenie.
CommonsWare
2
Wow, Twój przykład kodu to DOKŁADNY kod, który próbuję napisać! Co za zbieg okoliczności :)
Ilya Kogan
4
Czy nie byłoby ładniejsze / bardziej spójne użycie @TargetApi (Build.VERSION_CODES.HONEYCOMB), biorąc pod uwagę, że używasz Build.VERSION_CODES.HONEYCOMB w instrukcji if?
Oliver Pearmain
1
„że naprawiłem kod, aby działał tylko na poziomie API 11 i niższym, a nie na poziomie API 14 i niższym”. - czy nie masz na myśli „i powyżej”?
arekolek