Ograniczenia dotyczące interfejsów spoza SDK

Począwszy od Androida 9 (poziom interfejsu API 28) platforma ogranicza możliwość z jakich interfejsów może korzystać aplikacja. Te ograniczenia obowiązują za każdym razem, gdy aplikacja się odwołuje interfejsu innego niż SDK lub próbuje uzyskać nick za pomocą interfejsu Refion lub JNI. Te ograniczenia zostały nałożone, aby pomóc użytkownikom i deweloperom i zmniejszyć ryzyko awarii dla użytkowników oraz wdrożeń w sytuacjach awaryjnych dla programistów. Więcej informacji o tej decyzji znajdziesz w artykule Poprawa stabilności poprzez ograniczenie wykorzystania interfejsów innych niż SDK.

Różnice między interfejsami SDK i innymi niż SDK

Ogólnie publiczne interfejsy SDK to te, które są opisane w platformy Android Package Index. Obsługa interfejsów innych niż SDK lub szczegóły implementacji, które interfejs API może wyodrębniać, dlatego interfejsy te są może ulec zmianie bez powiadomienia.

Aby uniknąć awarii i nieoczekiwanego działania, aplikacje powinny używać tylko oficjalnie udokumentowanych części klas w pakiecie SDK. Oznacza to również, że nie należy metod dostępu lub pól, których nie ma w pakiecie SDK, za pomocą takich mechanizmów jak refleksja.

Listy interfejsów API spoza pakietu SDK

W każdej wersji Androida dodatkowe interfejsy inne niż SDK są ograniczone. Śr że ograniczenia te mogą wpływać na proces tworzenia wersji, że macie narzędzia do wykrywania korzystania z interfejsów spoza SDK, przekaż nam swoją opinię i zyskaj czas na zaplanowanie działań i dostosowanie się do nowych zasad.

Aby zminimalizować wpływ ograniczeń niezwiązanych z pakietem SDK na przepływ pracy w programie, funkcja interfejsy inne niż SDK są podzielone na listy, które określają stopień ich wykorzystania. ograniczone w zależności od tego, na który poziom interfejsu API są kierowane reklamy. Tabela poniżej opisuje każdą z tych list:

Lista Tagi kodu Opis
Lista zablokowanych
  • blocked
  • Wycofane: blacklist
Interfejsy inne niż SDK, których nie możesz używać bez względu na docelowy poziom interfejsu API. Jeśli aplikacja spróbuje uzyskać dostęp do jednego z tych interfejsów, system zwraca błąd.
Zablokowane warunkowo
  • max-target-x
  • Wycofane: greylist-max-x

Począwszy od Androida 9 (poziom interfejsu API 28) każdy poziom interfejsu API ma dostęp inny niż SDK interfejsów, które są ograniczone, gdy aplikacja jest kierowana na ten poziom API.

Te listy są oznaczone maksymalnym poziomem interfejsu API (max-target-x), na które aplikacja może kierować reklamy, zanim nie będzie mogła do interfejsów innych niż SDK z tej listy. Na przykład plik interfejs spoza SDK, który nie został zablokowany w Androidzie Pie, ale teraz jest zablokowany; w Androidzie 10 jest częścią max-target-p (greylist-max-p), gdzie „p”, oznacza Pie lub Android 9 (poziom interfejsu API 28).

Jeśli aplikacja próbuje uzyskać dostęp do interfejsu, do którego dostęp jest ograniczony docelowy poziom interfejsu API, działa tak, jakby interfejs API był częścią znaleźć się na liście zablokowanych.

Nieobsługiwane
  • unsupported
  • Wycofane: greylist
Interfejsy inne niż SDK, które nie mają ograniczeń i mogą być używane przez Twoją aplikację. Notatka jednak te interfejsy są nieobsługiwane może ulec zmianie bez powiadomienia. Te interfejsy powinny warunkowo zablokowane w przyszłych wersjach Androida w Lista max-target-x.
Pakiet SDK
  • Zarówno public-api, jak i sdk
  • Wycofane: zarówno public-api, jak i whitelist
Interfejsy, z których można swobodnie korzystać, a teraz są obsługiwane oficjalnie udokumentowana platforma Androida Indeks pakietu.
Testuj interfejsy API
  • test-api
Interfejsy używane do wewnętrznego testowania systemu, takie jak interfejsy API ułatwiają testowanie za pomocą Compatibility Test Suite (CTS). Testowe interfejsy API nie należą do pakietu SDK. Początek za Androida 11 (poziom interfejsu API 30), testowe interfejsy API są uwzględnione na liście zablokowanych, aplikacje nie mogą z nich korzystać niezależnie od docelowego poziomu interfejsu API. Wszystkie testowe interfejsy API nie są obsługiwane i mogą ulec zmianie bez powiadomienia. od poziomu interfejsu API platformy.

Możesz używać niektórych interfejsów spoza pakietu SDK (w zależności od docelowego interfejsu API aplikacji, ), użycie dowolnej metody lub pola niepochodzącego z pakietu SDK zawsze wiąże się z dużym ryzykiem uszkodzenia do aplikacji. Jeśli Twoja aplikacja korzysta z interfejsów innych niż SDK, należy zaplanować do interfejsów SDK lub innych rozwiązań. Jeśli nie możesz znaleźć jako alternatywę dla interfejsu innego niż SDK dla funkcji w aplikacji, żądanie nowego publicznego interfejsu API.

Określ, do której listy należy interfejs

Listy interfejsów innych niż SDK są tworzone w ramach platformy. Zobacz poniższych sekcji z informacjami o poszczególnych wersjach Androida.

Android 15

W przypadku Androida 15 (poziom interfejsu API 35) możesz pobrać poniższy plik z opisem wszystkie interfejsy spoza SDK i odpowiadające im listy:

Plik: hiddenapi-flags.csv

Suma kontrolna SHA-256: 40134e205e58922a708c453726b279a296e6a1f34a988abd90cec0f3432ea5a9

Aby dowiedzieć się więcej o zmianach list API niezwiązanych z pakietem SDK w Androidzie 15, przeczytaj artykuł Aktualizacje ograniczeń interfejsu spoza SDK w Androidzie 15.

Android 14

W przypadku Androida 14 (poziom interfejsu API 34) możesz pobrać poniższy plik z opisem wszystkie interfejsy spoza SDK i odpowiadające im listy:

Plik: hiddenapi-flags.csv

Suma kontrolna SHA-256: 7e00db074cbe51c51ff4b411f7b48e98692951395c5c17d069c822cc1d0eae0f

Aby dowiedzieć się więcej o zmianach list API niezwiązanych z pakietem SDK w Androidzie 14, przeczytaj artykuł Aktualizacje ograniczeń interfejsu spoza SDK w Androidzie 14.

Android 13

W przypadku Androida 13 (poziom interfejsu API 33) możesz pobrać poniższy plik z opisem wszystkie interfejsy spoza SDK i odpowiadające im listy:

Plik: hiddenapi-flags.csv

Suma kontrolna SHA-256: 233a277aa8ac475b6df61bffd95665d86aac6eb2ad187b90bf42a98f5f2a11a3

Aby dowiedzieć się więcej o zmianach list API niezwiązanych z pakietem SDK w Androidzie 13, w tym sugerowane publiczne alternatywne interfejsy API dla interfejsów API, które są warunkowo zablokowane w Androidzie 13: Aktualizacje interfejsu innego niż SDK ograniczenia w Androidzie 13.

Android 12

W przypadku Androida 12 (poziom interfejsu API 31) możesz pobrać poniższy plik z opisem wszystkie interfejsy spoza SDK i odpowiadające im listy:

Plik: hiddenapi-flags.csv

Suma kontrolna SHA-256: 40674ff4291eb268f86561bf687e69dbd013df9ec9531a460404532a4ac9a761

Aby dowiedzieć się więcej o zmianach dotyczących list interfejsów API spoza pakietu SDK w Androidzie 12, w tym sugerowane publiczne alternatywne interfejsy API dla interfejsów API, które są warunkowo zablokowane w Androidzie 12, zobacz Lista zmian dla Android 12.

Android 11

W przypadku Androida 11 (poziom interfejsu API 30) możesz pobrać poniższy plik, który: wszystkie interfejsy spoza SDK i odpowiadające im listy:

Plik: hiddenapi-flags.csv

Suma kontrolna SHA-256: a19d839f4f61dc9c94960ae977b2e0f3eb30f880ba1ffe5108e790010b477a56

Aby dowiedzieć się więcej o zmianach list API niezwiązanych z pakietami SDK w Androidzie 11, w tym sugerowane publiczne alternatywne interfejsy API dla interfejsów API, które są warunkowo blokowane w Android 11: zobacz listę zmian w Androidzie 11.

Android 10

W przypadku Androida 10 (poziom interfejsu API 29) możesz pobrać poniższy plik, który wszystkie interfejsy spoza SDK i odpowiadające im listy:

Plik: hiddenapi-flags.csv

Suma kontrolna SHA-256: f22a59c215e752777a114bd9b07b0b6b4aedfc8e49e6efca0f99681771c5bfeb

Aby dowiedzieć się więcej o zmianach list API niezwiązanych z pakietami SDK w Androidzie 10, w tym sugerowane publiczne alternatywne interfejsy API dla interfejsów API, które są warunkowo blokowane w Android 10: zobacz listę zmian w Androidzie 10.

Android 9

W przypadku Androida 9 (poziom interfejsu API 28) poniższy plik tekstowy zawiera listę Interfejsy API spoza pakietu SDK, które nie są objęte ograniczeniami (szara lista): hiddenapi-light-greylist.txt

Lista zablokowanych (blacklist) i lista warunkowo zablokowanych interfejsów API (ciemnoszary) ) są pobierane w momencie kompilacji.

Generuj listy z AOSP

Podczas pracy z AOSP możesz wygenerować plik hiddenapi-flags.csv, który zawiera wszystkie interfejsy spoza SDK i odpowiadające im listy. Aby to zrobić: pobierz źródło AOSP, a następnie uruchom to polecenie:

m out/soong/hiddenapi/hiddenapi-flags.csv

Znajdziesz go w tej lokalizacji:

out/soong/hiddenapi/hiddenapi-flags.csv

Oczekiwane działanie przy dostępie do ograniczonych interfejsów spoza pakietu SDK

W tabeli poniżej znajdziesz opis zachowania, którego możesz się spodziewać, jeśli Twoja aplikacja próbuje uzyskać dostęp do interfejsu innego niż SDK, który jest na liście zablokowanych.

Metody dostępu Wynik
Instrukcja Dalvik odnosząca się do pola NoSuchFieldError rzucony
Instrukcja Dalvik odnosząca się do metody NoSuchMethodError rzucony
Odbicie za pomocą Class.getDeclaredField() lub Class.getField() NoSuchFieldException rzucony
Odbicie z użyciem elementów Class.getDeclaredMethod(), Class.getMethod() NoSuchMethodException rzucony
Odbicie z użyciem elementów Class.getDeclaredFields(), Class.getFields() Użytkownicy, którzy nie korzystają z pakietu SDK, nie pojawiają się w wynikach
Odbicie z użyciem elementów Class.getDeclaredMethods(), Class.getMethods() Użytkownicy, którzy nie korzystają z pakietu SDK, nie pojawiają się w wynikach
JNI z env->GetFieldID() NULL zwrócone, NoSuchFieldError rzuca
JNI z env->GetMethodID() NULL zwrócone, NoSuchMethodError rzuca

Testowanie aplikacji pod kątem interfejsów innych niż SDK

Istnieje kilka metod, które można wykorzystać do testowania interfejsów innych niż SDK w do aplikacji.

Testowanie za pomocą aplikacji z możliwością debugowania

Możesz przetestować interfejsy inne niż SDK, tworząc i uruchamiając aplikację możliwą do debugowania na urządzeniu lub w emulatorze z Androidem 9 (poziom interfejsu API 28); wyższe. Upewnij się, że urządzenie lub emulator jest zgodne docelowy poziom interfejsu API aplikacji.

Podczas testów w aplikacji system wydrukuje komunikat logu, jeśli dostęp do pewnych interfejsów spoza SDK. Możesz przeglądać komunikaty logu aplikacji aby uzyskać następujące informacje:

  • Klasa, nazwa i typ deklarowania (w formacie używanym przez środowisko wykonawcze Androida).
  • Środki dostępu: połączenie, za pomocą refleksji lub JNI.
  • Do której listy należy interfejs inny niż SDK.

Aby uzyskać dostęp do tych komunikatów logu, możesz użyć narzędzia adb logcat. Są one widoczne w Identyfikator PID uruchomionej aplikacji. Wpis w dzienniku może na przykład wyglądać tak:

Accessing hidden field Landroid/os/Message;->flags:I (light greylist, JNI)

Testowanie za pomocą interfejsu StrictMode API

Możesz też przeprowadzać testy w interfejsach innych niż SDK za pomocą interfejsu API StrictMode. Użyj detectNonSdkApiUsage, aby włączyć tę funkcję. Po włączeniu StrictMode API, możesz otrzymywać wywołanie zwrotne za każdym razem, gdy używasz interfejsu innego niż SDK. za pomocą interfejsu penaltyListener, gdzie możesz zaimplementować niestandardowe z obsługą klienta. Obiekt Violation podany w wywołaniu zwrotnym pochodzi z Throwable, a załączony zrzut stosu przedstawia kontekst użycia.

Przetestuj za pomocą narzędzia Veridex

Możesz też uruchomić narzędzie do analizy statycznej Veridex. Narzędzie Veridex skanuje całą bazę kodu pliku APK, w tym biblioteki zewnętrzne, oraz raportuje wszelkie znalezione przypadki użycia interfejsów innych niż SDK.

Ograniczenia narzędzia Weridex są następujące:

  • Nie udało się wykryć wywołań za pomocą JNI.
  • Może wykryć tylko podzbiór wywołań za pomocą odbicia.
  • Analiza nieaktywnych ścieżek kodu jest ograniczona do kontroli na poziomie interfejsu API.
  • Można go uruchomić tylko na komputerach obsługujących instrukcje SSE4.2 i POPCNT.

Windows

Natywne pliki binarne systemu Windows nie są dostępne, ale możesz uruchomić narzędzie Veridex Windows przez uruchomienie plików binarnych Linuksa przy użyciu podsystemu Windows dla tego systemu. (WSL). Przed wykonaniem czynności opisanych w tej sekcji zainstaluj WSL i wybierz Ubuntu jako dystrybucję Linuksa.

Po zainstalowaniu systemu Ubuntu uruchom terminal Ubuntu, a następnie wykonaj te czynności:

  1. Pobierz narzędzie Veridex ze środowiska wykonawczego Androida. z repozytorium.
  2. Wyodrębnij zawartość pliku appcompat.tar.gz.
  3. W rozpakowanym folderze znajdź plik veridex-linux.zip i rozpakuj go.
  4. Przejdź do rozpakowanego folderu i uruchom to polecenie, przy czym your-app.apk to plik APK, który chcesz przetestować:

    ./appcompat.sh --dex-file=your-app.apk
    

macOS,

Aby uruchomić narzędzie Veridex w systemie macOS, wykonaj te czynności:

  1. Pobierz narzędzie Veridex ze środowiska wykonawczego Androida. z repozytorium.
  2. Wyodrębnij zawartość pliku appcompat.tar.gz.
  3. W rozpakowanym folderze znajdź plik veridex-mac.zip i rozpakuj go.
  4. Przejdź do rozpakowanego folderu i uruchom to polecenie, przy czym /path-from-root/your-app.apk to ścieżka do pliku APK który chcesz przetestować, zaczynając od katalogu głównego systemu:

    ./appcompat.sh --dex-file=/path-from-root/your-app.apk
    

Linux

Aby uruchomić narzędzie Veridex w systemie Linux, wykonaj następujące czynności:

  1. Pobierz narzędzie Veridex ze środowiska wykonawczego Androida. z repozytorium.
  2. Wyodrębnij zawartość pliku appcompat.tar.gz.
  3. W rozpakowanym folderze znajdź plik veridex-linux.zip i rozpakuj go.
  4. Przejdź do rozpakowanego folderu i uruchom to polecenie, przy czym your-app.apk to plik APK, który chcesz przetestować:

    ./appcompat.sh --dex-file=your-app.apk
    

Testowanie za pomocą narzędzia Android Studio Linter

Za każdym razem, gdy tworzysz aplikację w Android Studio, narzędzie Lint sprawdza w kodzie potencjalnych problemów. Jeśli Twoja aplikacja korzysta z interfejsów innych niż SDK, możesz zobaczyć błędy lub ostrzeżenia związane z kompilacją, w zależności od listy tych interfejsów; do.

Możesz też uruchomić narzędzie Lint z poziomu wiersza poleceń lub przeprowadzić inspekcji ręcznie w konkretnym projekcie, folderze lub pliku.

Testowanie w Konsoli Play

Gdy prześlesz aplikację na ścieżkę testów w Konsoli Play, jest automatycznie testowany pod kątem potencjalnych problemów, a raport przed opublikowaniem jest . Jeśli Twoja aplikacja używa interfejsów spoza pakietu SDK, w raport przed opublikowaniem, w zależności od listy, do której należą te interfejsy.

Więcej informacji znajdziesz w sekcji Zgodność z Androidem w artykule Używanie przed opublikowaniem aby wykryć problemy.

Poproś o nowy publiczny interfejs API

Jeśli nie możesz znaleźć alternatywy dla interfejsu innego niż SDK dla danej funkcji aplikacji, możesz zażądać nowego publicznego interfejsu API, tworząc prośbę o dodanie funkcji. w naszym narzędziu.

Podczas tworzenia prośby o dodanie funkcji podaj te informacje:

  • Jakiego nieobsługiwanego interfejsu API używasz, wraz z pełnym deskryptorem widocznym w komunikat dziennika Accessing hidden ....
  • Dlaczego trzeba korzystać z tych interfejsów API, w tym szczegółowe informacje o ogólnych interfejsach API funkcji, do których jest niezbędny interfejs API, a nie tylko szczegółów niskiego poziomu.
  • Dlaczego powiązane publiczne interfejsy API pakietu SDK są niewystarczające do realizacji Twoich celów.
  • Wszelkie inne wypróbowane przez Ciebie rozwiązania i przyczyny niepowodzenia.

Podanie tych informacji w prośbie o funkcję zwiększy prawdopodobieństwo przyznania nowego publicznego interfejsu API.

Inne pytania

W tej sekcji znajdziesz odpowiedzi na inne pytania deweloperów najczęstsze pytania:

Pytania ogólne

Jak Google może mieć pewność, że za pomocą narzędzia do śledzenia problemów będzie w stanie uwzględnić potrzeby wszystkich aplikacji?

Wstępne listy na Androida 9 (poziom interfejsu API 28) stworzyliśmy na podstawie analiza aplikacji uzupełnionych następującymi metodami:

  • ręczne testowanie najpopularniejszych aplikacji z Google Play i innych aplikacji
  • raporty wewnętrzne
  • automatyczne zbieranie danych od użytkowników wewnętrznych
  • raporty dotyczące wersji przedpremierowej dla programistów
  • dodatkowej analizy statycznej, która miała zachowawczo obejmować wyniki fałszywie pozytywne

Analizując listy dla każdej nowej wersji, bierzemy pod uwagę wykorzystanie interfejsu API a także opiniami deweloperów.

Jak mogę włączyć dostęp do interfejsów innych niż SDK?

Możesz włączyć dostęp do interfejsów innych niż SDK na urządzeniach używanych do programowania za pomocą narzędzia adb polecenia do zmiany zasady egzekwowania interfejsu API. Używane przez Ciebie polecenia różnią się, w zależności od poziomu interfejsu API. Te polecenia nie wymagają urządzenia z dostępem do roota.

Android 10 (poziom interfejsu API 29) lub nowszy

Aby włączyć dostęp, użyj tego narzędzia adb

polecenie:

adb shell settings put global hidden_api_policy  1

Aby zresetować zasadę egzekwowania interfejsu API do ustawień domyślnych, użyj to polecenie:

adb shell settings delete global hidden_api_policy
Android 9 (poziom 28 interfejsu API)

Aby włączyć dostęp, użyj tych poleceń adb:

adb shell settings put global hidden_api_policy_pre_p_apps  1
adb shell settings put global hidden_api_policy_p_apps 1

Aby zresetować zasadę egzekwowania interfejsu API do ustawień domyślnych, użyj następujące polecenia:

adb shell settings delete global hidden_api_policy_pre_p_apps
adb shell settings delete global hidden_api_policy_p_apps

W zasadzie egzekwowania interfejsu API możesz ustawić jedną z tych liczb całkowitych: wartości:

  • 0. Wyłącz wykrywanie interfejsów innych niż SDK. Użycie tego ustawienia wyłącza wszystkich komunikatów logu dotyczących użycia interfejsu innego niż SDK i uniemożliwia testowanie przy użyciu interfejsu API StrictMode. To ustawienie nie jest zalecane.
  • 1. Włącz dostęp do wszystkich interfejsów spoza SDK, ale drukuj komunikaty dziennika za pomocą ostrzeżenia o wykorzystaniu interfejsu innego niż SDK. To ustawienie pozwala też przetestować aplikację za pomocą interfejsu API StrictMode.
  • 2. Nie zezwalaj na korzystanie z interfejsów innych niż SDK, które znajdują się na liście zablokowanych lub są warunkowo zablokowane na docelowym poziomie interfejsu API.

Pytania o listy interfejsów innych niż SDK

Gdzie znajdę w obrazie systemu listy interfejsów API spoza pakietu SDK?

Są one zakodowane w bitach flag dostępu pola i metod w plikach .dex platformy. W obrazie systemu nie ma osobnego pliku, który zawiera te listy.

Czy listy interfejsów API spoza pakietu SDK są takie same na różnych urządzeniach OEM z tą samą wersją Androida?

Producenci OEM mogą dodawać do czarnej (czarnej listy) własne interfejsy, ale nie mogą usunięcia interfejsów z list interfejsów API innych niż SDK AOSP. CDD zapobiega takim zmianom. a testy CTS dają pewność, że lista jest egzekwowana w środowisku wykonawczym Androida.

Czy są jakieś ograniczenia dotyczące interfejsów innych niż NDK w kodzie natywnym?

Pakiet Android SDK zawiera interfejsy Java. Platforma zaczęła ograniczać dostęp do interfejsów innych niż NNDK na potrzeby natywnego kodu C/C++ w Androidzie 7 (poziom API 26). Więcej informacji znajdziesz w artykule Zwiększanie stabilności za pomocą symbolu prywatnego C/C++ Ograniczenia na Androidzie N.

Czy planujecie ograniczyć manipulowanie plikami dex2oat i DEX?

Nie planujemy ograniczyć dostępu do pliku binarnego dex2oat, ale format pliku DEX będzie stabilny ani nie będzie używał publicznego interfejsu części podane publicznie w formacie pliku wykonywalnego Dalvik. Zastrzegamy sobie prawo do zmodyfikowania lub usunięcia instrukcji dex2oat oraz nieokreślonych części formatu DEX. Zwróć też uwagę, że pliki pochodne tworzone przez dex2oat takie jak ODEX (znane też jako OAT), VDEX i CDEX, to formaty nieokreślone.

Co zrobić, jeśli kluczowy pakiet SDK innej firmy (np. zaciemniający) nie może uniknąć użycia interfejsów innych niż SDK, ale zobowiązuje się zachować zgodność z przyszłymi wersjami Androida? Czy w tym przypadku Android może zrezygnować z wymagań dotyczących zgodności?

Nie planujemy zrezygnować z wymagań dotyczących zgodności z poszczególnymi pakietami SDK. Jeśli deweloper pakietu SDK może utrzymać zgodność tylko w zależności od interfejsów nieobsługiwanych (dawniej szare), powinien zacząć planować migrację interfejsów SDK lub innych rozwiązań alternatywnych oraz żądania nowego publicznego interfejsu API, nie mogą znaleźć alternatywy dla interfejsu innego niż SDK.

Czy ograniczenia interfejsu innego niż SDK mają zastosowanie do wszystkich aplikacji, w tym aplikacji systemowych i aplikacji własnych, a nie tylko aplikacji innych firm?

Tak, jednak wykluczamy aplikacje podpisane kluczem platformy i obrazem systemu aplikacji. Pamiętaj, że te wyłączenia dotyczą tylko aplikacji, które są częścią systemu (lub w zaktualizowanych aplikacjach z obrazem systemu). Ta lista jest przeznaczona tylko dla aplikacji, które: za pomocą interfejsów API platformy prywatnej, a nie interfejsów SDK (gdzie LOCAL_PRIVATE_PLATFORM_APIS := true).