Od Androida 9 (poziom interfejsu API 28) platforma ogranicza interfejsy spoza pakietu SDK, których może używać aplikacja. Te ograniczenia obowiązują, gdy aplikacja odwołuje się do interfejsu innego niż SDK lub próbuje uzyskać jego uchwyt za pomocą mechanizmu odbicia 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 nie-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. Wiemy, że te ograniczenia mogą mieć wpływ na Twój proces publikowania. Chcemy jednak zapewnić Ci narzędzia do wykrywania korzystania z interfejsów innych niż SDK, przekazać nam opinię oraz czas na zaplanowanie 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 |
|
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 |
|
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
( 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 |
|
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 |
|
Interfejsy, których można używać swobodnie i które są teraz obsługiwane w ramach oficjalnie udokumentowanego frameworka Androida Package Index. |
Testuj interfejsy 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 API 35) możesz pobrać plik, który opisuje wszystkie interfejsy inne niż SDK i odpowiednie 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
Więcej informacji o zmianach w liście interfejsów API spoza pakietu SDK w Androidzie 14 znajdziesz w artykule Zmiany ograniczeń interfejsów API spoza pakietu 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
Więcej informacji o zmianach w liście interfejsów API spoza pakietu SDK w Androidzie 13, w tym o sugerowanych alternatywnych interfejsach API dla interfejsów API, które są blokowane warunkowo w Androidzie 13, znajdziesz w artykule Zmiany w ograniczeniach interfejsów API spoza pakietu SDK 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 API 30) możesz pobrać plik, który opisuje wszystkie interfejsy inne niż SDK i odpowiednie 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.
Generowanie list 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
Plik znajdziesz w tym miejscu:
out/soong/hiddenapi/hiddenapi-flags.csv
Oczekiwane działanie przy dostępie do ograniczonych interfejsów spoza pakietu SDK
Z tabeli poniżej dowiesz się, czego możesz się spodziewać, gdy Twoja aplikacja będzie próbować uzyskać dostęp do interfejsu innego niż SDK, który znajduje się na liście zablokowanych.
Metody dostępu | Wynik |
---|---|
Instrukcja Dalvik odwołująca się do pola | NoSuchFieldError wyrzucono |
Instrukcja Dalvik odnosząca się do metody | NoSuchMethodError rzucony |
Odbicie za pomocą Class.getDeclaredField() lub Class.getField() |
NoSuchFieldException rzucony |
Odbicie przy użyciu 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 spoza pakietu SDK nie są uwzględniani 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 do 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żej. 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 deklaracji (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
. Aby to zrobić, użyj metody detectNonSdkApiUsage
. 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:
- Pobierz narzędzie veridex z repozytorium gotowych obrazów środowiska wykonawczego Androida.
- Wyodrębnij zawartość pliku
appcompat.tar.gz
. - W rozpakowanym folderze znajdź plik
veridex-linux.zip
i rozpakuj go. Przejdź do rozpakowanego folderu, a potem uruchom to polecenie, gdzie
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:
- Pobierz narzędzie veridex z repozytorium gotowych obrazów środowiska wykonawczego Androida.
- Wyodrębnij zawartość pliku
appcompat.tar.gz
. - W rozpakowanym folderze znajdź plik
veridex-mac.zip
i rozpakuj go. 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:
- Pobierz narzędzie Veridex ze środowiska wykonawczego Androida. z repozytorium.
- Wyodrębnij zawartość pliku
appcompat.tar.gz
. - W rozpakowanym folderze znajdź plik
veridex-linux.zip
i rozpakuj go. 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 musisz używać tych interfejsów API, w tym szczegóły dotyczące funkcji wysokiego poziomu, do której są one potrzebne, a nie tylko szczegóły 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.
Podając te informacje w prośbie o funkcję, zwiększasz prawdopodobieństwo udostępnienia 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
- dodatkowa analiza statyczna, która została zaprojektowana tak, aby konserwatywnie uwzględniać więcej wyników fałszywie dodatnich;
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 spoza pakietu SDK na urządzeniach deweloperskich, używając poleceń adb do zmiany zasad egzekwowania interfejsów API. Używane przez Ciebie polecenia różnią się, w zależności od poziomu interfejsu API. Te polecenia nie wymagają zrootowanego urządzenia.
- 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 dotyczące list 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 innych niż SDK są takie same na różnych urządzeniach OEM z tymi samymi wersjami 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.
Pytania dotyczące zgodności powiązanych aplikacji
Czy są jakieś ograniczenia dotyczące interfejsów innych niż NDK w kodzie natywnym?
Pakiet SDK Androida 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 na temat ulepszania 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 jest stabilny i nie powinna być części podane publicznie w formacie wykonywalnym 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. narzędzie do zaciemniania) nie może używać interfejsów spoza pakietu SDK, ale zobowiązuje się do zachowania zgodności 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 niebędącego pakietem SDK dotyczą wszystkich aplikacji, w tym aplikacji systemowych i 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
).