Zmiany w działaniu: aplikacje kierowane na interfejs API w wersji 29 lub nowszej

Android 10 wprowadza zaktualizowane zmiany w działaniu systemu, które mogą mieć wpływ na Twoją aplikację. Zmiany wymienione na tej stronie dotyczą wyłącznie aplikacji kierowanych na API w wersji 29 lub nowszej. Jeśli Twoja aplikacja ustawia wartość targetSdkVersion na „29” lub wyższą, zmodyfikuj ją tak, aby w odpowiednich przypadkach prawidłowo obsługiwała te zachowania.

Zapoznaj się też z listą zmian w zachowaniu, które mają wpływ na wszystkie aplikacje działające na Androidzie 10.

Uwaga: oprócz zmian wymienionych na tej stronie Android 10 wprowadza wiele zmian i ograniczeń związanych z ochroną prywatności, w tym:

  • Ograniczony dostęp do miejsca na dane
  • Dostęp do numeru seryjnego urządzenia USB
  • Możliwość włączania, wyłączania i konfigurowania Wi-Fi
  • Uprawnienia dostępu do lokalizacji w przypadku interfejsów API do obsługi łączności

Te zmiany, które dotyczą aplikacji kierowanych na interfejs API na poziomie 29 lub wyższym, zwiększają prywatność użytkowników. Więcej informacji o tym, jak dostosować się do tych zmian, znajdziesz na stronie Zmiany dotyczące prywatności.

Zmiany w ograniczeniach dotyczących interfejsów innych niż SDK

Aby zapewnić stabilność i kompatybilność aplikacji, platforma zaczęła ograniczać, których interfejsów spoza SDK może używać aplikacja w Androidzie 9 (poziom API 28). Android 10 zawiera zaktualizowane listy ograniczonych interfejsów spoza SDK, które powstały na podstawie współpracy z programistami Androida i najnowszych testów wewnętrznych. Chcemy mieć pewność, że zanim ograniczymy interfejsy inne niż SDK, dostępne będą publiczne alternatywy.

Jeśli nie kierujesz aplikacji na Androida 10 (poziom interfejsu API 29), niektóre z tych zmian mogą nie mieć na Ciebie natychmiastowego wpływu. Obecnie możesz używać niektórych interfejsów spoza SDK (w zależności od docelowego poziomu interfejsu API aplikacji), ale korzystanie z dowolnej metody lub pola spoza SDK zawsze wiąże się z wysokim ryzykiem awarii aplikacji.

Jeśli nie masz pewności, czy Twoja aplikacja używa interfejsów innych niż SDK, możesz to sprawdzić, testując aplikację. Jeśli Twoja aplikacja korzysta z interfejsów spoza SDK, zacznij planować przejście na alternatywne rozwiązania SDK. Rozumiemy jednak, że w przypadku niektórych aplikacji używanie interfejsów innych niż SDK jest uzasadnione. Jeśli nie możesz znaleźć alternatywy dla używania interfejsu innego niż SDK w przypadku funkcji w aplikacji, poproś o nowy publiczny interfejs API.

Więcej informacji znajdziesz w artykule Zmiany w ograniczeniach dotyczących interfejsów innych niż SDK w Androidzie 10 oraz w sekcji Ograniczenia dotyczące interfejsów innych niż SDK.

Pamięć współdzielona

Ashmem zmienił format map dalvik w /proc/<pid>/maps, co ma wpływ na aplikacje, które bezpośrednio analizują plik map. Deweloperzy aplikacji powinni przetestować format /proc/<pid>/maps na urządzeniach z Androidem 10 lub nowszym i odpowiednio go przeanalizować, jeśli aplikacja zależy od formatów map dalvik.

Aplikacje przeznaczone na Androida 10 nie mogą bezpośrednio używać ashmem (/dev/ashmem), ale muszą uzyskiwać dostęp do pamięci współdzielonej za pomocą klasy NDK ASharedMemory. Aplikacje nie mogą też wykonywać bezpośrednich wywołań IOCTL do istniejących deskryptorów plików ashmem. Zamiast tego muszą używać klasy ASharedMemory NDK lub interfejsów API Java Androida do tworzenia regionów pamięci współdzielonej. Ta zmiana zwiększa bezpieczeństwo i stabilność podczas pracy z pamięcią współdzieloną, co poprawia wydajność i bezpieczeństwo Androida.

Usunięto uprawnienia do wykonywania w katalogu domowym aplikacji

Wykonywanie plików z katalogu głównego aplikacji z możliwością zapisu jest naruszeniem zasad. Aplikacje powinny wczytywać tylko kod binarny osadzony w pliku APK aplikacji.

Niezaufane aplikacje na Androida 10 nie mogą bezpośrednio wywoływać execve()w przypadku plików w katalogu głównym aplikacji.

Dodatkowo aplikacje kierowane na Androida 10 nie mogą modyfikować w pamięci kodu wykonywalnego z plików otwartych za pomocą funkcji dlopen() i oczekiwać, że zmiany zostaną zapisane na dysku, ponieważ biblioteka nie mogła zostać zmapowana PROT_EXEC za pomocą deskryptora pliku z możliwością zapisu. Obejmuje to wszystkie pliki obiektów współdzielonych (.so) z relokacjami tekstu.

Środowisko wykonawcze Androida akceptuje tylko pliki OAT generowane przez system

Środowisko wykonawcze Androida (ART) nie wywołuje już funkcji dex2oat z procesu aplikacji. Ta zmiana oznacza, że ART będzie akceptować tylko pliki OAT wygenerowane przez system.

Wymuszanie poprawności kompilacji AOT w ART

W przeszłości kompilacja z wyprzedzeniem (AOT) wykonywana przez środowisko wykonawcze Androida (ART) mogła powodować awarie w czasie działania, jeśli środowisko ścieżki klasy nie było takie samo w czasie kompilacji i w czasie działania. Android 10 i nowsze wersje zawsze wymagają, aby te konteksty środowiska były takie same, co powoduje następujące zmiany w działaniu:

  • Niestandardowe programy ładujące klasy, czyli programy ładujące klasy napisane przez aplikacje (w przeciwieństwie do programów ładujących klasy z pakietu dalvik.system), nie są kompilowane z wyprzedzeniem. Dzieje się tak, ponieważ ART nie może w czasie działania wiedzieć o niestandardowej implementacji wyszukiwania klas.
  • Dodatkowe pliki DEX, czyli pliki DEX wczytywane ręcznie przez aplikacje, które nie znajdują się w głównym pliku APK, są kompilowane AOT w tle. Dzieje się tak, ponieważ kompilacja przy pierwszym użyciu może być zbyt kosztowna, co prowadzi do niepożądanego opóźnienia przed wykonaniem. W przypadku aplikacji zalecamy stosowanie podziałów i rezygnację z pomocniczych plików DEX.
  • Biblioteki współdzielone w Androidzie (wpisy <library> i <uses-library> w pliku manifestu Androida) są implementowane przy użyciu innej hierarchii modułów ładujących klasy niż ta, która była używana w poprzednich wersjach platformy.

Zmiany uprawnień dotyczące intencji pełnoekranowych

Aplikacje kierowane na Androida 10 lub nowszego, które używają powiadomień z intencjami pełnoekranowymi, muszą w pliku manifestu aplikacji poprosić o uprawnienie USE_FULL_SCREEN_INTENT. Jest to zwykłe uprawnienie, więc system automatycznie przyznaje je aplikacji, która o nie prosi.

Jeśli aplikacja kierowana na Androida 10 lub nowszego spróbuje utworzyć powiadomienie z intencją pełnoekranową bez żądania niezbędnych uprawnień, system zignoruje intencję pełnoekranową i wyświetli ten komunikat w dzienniku:

Package your-package-name: Use of fullScreenIntent requires the USE_FULL_SCREEN_INTENT permission

Obsługa urządzeń składanych

Android 10 wprowadza zmiany, które obsługują urządzenia składane i urządzenia z dużym ekranem.

Gdy aplikacja działa na Androidzie 10, metody onResume()onPause() działają inaczej. Gdy w trybie wielu okien lub wielu wyświetlaczy jednocześnie pojawia się kilka aplikacji, wszystkie aktywności na pierwszym planie, na których można się skupić, w widocznych stosach są w stanie wznowienia, ale tylko jedna z nich, aktywność „najbardziej na pierwszym planie”, jest aktywna. W przypadku wersji starszych niż Android 10 w systemie można wznowić tylko jedną aktywność naraz, a wszystkie inne widoczne aktywności są wstrzymane.

Nie myl „fokusowania” z aktywnością „najwyższego poziomu wznowienia”. System przypisuje priorytety do aktywności na podstawie kolejności Z, aby nadać wyższy priorytet aktywnościom, z którymi użytkownik ostatnio wchodził w interakcję. Aktywność może być wznowiona na pierwszym planie, ale nie musi być aktywna (np. gdy jest rozwinięty panel powiadomień).

W Androidzie 10 (API na poziomie 29) i nowszych wersjach możesz zasubskrybować wywołanie zwrotne onTopResumedActivityChanged(), aby otrzymywać powiadomienia, gdy Twoja aktywność uzyska lub utraci najwyższą pozycję wznowienia. Jest to odpowiednik stanu wznowienia sprzed Androida 10 i może być przydatny jako wskazówka, jeśli aplikacja używa zasobów wyłącznych lub pojedynczych, które mogą wymagać udostępniania innym aplikacjom.

Zmieniło się też działanie atrybutu manifestu resizeableActivity. Jeśli aplikacja ustawi wartość resizeableActivity=false w Androidzie 10 (poziom interfejsu API 29) lub nowszym, może zostać przełączona w tryb zgodności w przypadku zmiany dostępnego rozmiaru ekranu lub przeniesienia aplikacji z jednego ekranu na inny.

Aplikacje mogą używać atrybutu android:minAspectRatio, który został wprowadzony w Androidzie 10, aby wskazywać proporcje ekranu, które obsługuje aplikacja.

Od wersji 3.5 narzędzie emulatora Androida Studio zawiera wirtualne urządzenia o przekątnej 7,3 cala i 8 cali, które umożliwiają testowanie kodu na większych ekranach.

Więcej informacji znajdziesz w artykule Projektowanie aplikacji na urządzenia składane.