Zmiany w działaniu: wszystkie aplikacje

Android 10 obejmuje zmiany w działaniu, które mogą mieć wpływ na Twoją aplikację. Zmiany wymienione na tej stronie dotyczą Twojej aplikacji uruchomionej na Androidzie 10, niezależnie od jej targetSdkVersion. Przetestuj aplikację i w razie potrzeby zmodyfikuj ją, by obsługiwała te zmiany.

Jeśli parametr targetSdkVersion Twojej aplikacji to 29 lub więcej, musisz wprowadzić dodatkowe zmiany. Więcej informacji znajdziesz w artykule o zmianach w działaniu aplikacji, które są kierowane na wersję 29.

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

  • Dostęp do lokalizacji urządzenia w tle
  • Rozpoczyna się aktywność w tle
  • Informacje o powiązaniach z kontaktami
  • randomizacja adresów MAC
  • Metadane kamery
  • Model uprawnień

Te zmiany mają wpływ na wszystkie aplikacje i zwiększają prywatność użytkowników. Aby dowiedzieć się więcej o obsłudze tych zmian, wejdź na stronę Zmiany dotyczące prywatności.

Ograniczenia interfejsu spoza SDK

Aby zapewnić stabilność i zgodność aplikacji, platforma zaczęła ograniczać możliwość używania interfejsów innych niż SDK w Androidzie 9 (poziom API 28). Android 10 zawiera zaktualizowane listy ograniczonych interfejsów spoza SDK przygotowane na podstawie współpracy z deweloperami aplikacji na Androida i najnowszych testów wewnętrznych. Naszym celem jest udostępnienie publicznych alternatywnych rozwiązań, zanim ograniczymy dostęp do interfejsów innych niż SDK.

Jeśli nie kierujesz reklam na Androida 10 (poziom interfejsu API 29), niektóre z tych zmian mogą nie od razu Cię dotyczyć. Mimo że obecnie można korzystać z niektórych interfejsów innych niż SDK (w zależności od docelowego poziomu interfejsu API aplikacji), użycie dowolnej metody lub pola spoza pakietu SDK zawsze wiąże się z dużym ryzykiem uszkodzenia aplikacji.

Jeśli nie masz pewności, czy Twoja aplikacja korzysta z interfejsów innych niż SDK, możesz to sprawdzić, przetestując aplikację. Jeśli Twoja aplikacja korzysta z interfejsów innych niż SDK, zacznij planować migrację do alternatywnych pakietów SDK. Zdajemy sobie jednak sprawę, że niektóre aplikacje mogą prawidłowo korzystać z interfejsów innych niż SDK. Jeśli nie możesz znaleźć w swojej aplikacji interfejsu innego niż interfejs SDK, musisz poprosić o nowy publiczny interfejs API.

Więcej informacji znajdziesz w artykule Aktualizacje ograniczeń związanych z interfejsami innymi niż SDK w Androidzie 10 oraz w artykule Ograniczenia dotyczące interfejsów spoza SDK.

Nawigacja przy użyciu gestów

Począwszy od Androida 10 użytkownicy mogą włączyć nawigację przy użyciu gestów na urządzeniu. Jeśli użytkownik włączy nawigację przy użyciu gestów, będzie to miało wpływ na wszystkie aplikacje na urządzeniu, niezależnie od tego, czy są kierowane na poziom API 29. Jeśli na przykład użytkownik przesunie palcem od krawędzi ekranu, system zinterpretuje ten gest jako przejście wstecz, chyba że aplikacja specjalnie zastąpi ten gest na części ekranu.

Aby Twoja aplikacja była zgodna z nawigacją przy użyciu gestów, musisz rozciągnąć jej zawartość od krawędzi do krawędzi i odpowiednio radzić sobie z sprzecznymi gestami. Więcej informacji znajdziesz w dokumentacji nawigacji przy użyciu gestów.

NDK

Android 10 zawiera następujące zmiany NDK.

Obiekty udostępnione nie mogą zawierać relokacji tekstu

W Androidzie 6.0 (poziom interfejsu API 23) zakazano używania relokacji tekstu w obiektach udostępnionych. Kod musi być ładowany w takiej postaci, w jakiej jest, i nie można go modyfikować. Ta zmiana wydłuża czas wczytywania aplikacji i zwiększa bezpieczeństwo.

SELinux wymusza to ograniczenie w aplikacjach kierowanych na Androida 10 lub nowszego. Jeśli takie aplikacje nadal używają udostępnionych obiektów zawierających relokacje tekstu, istnieje duże ryzyko uszkodzenia.

Zmiany w bibliotekach Bionic i ścieżkach dynamicznego łączącego

Począwszy od Androida 10 kilka ścieżek to łącza symboliczne, a nie zwykłe pliki. Aplikacje, które korzystały z tych ścieżek jako zwykłe pliki, mogą nie działać prawidłowo:

  • /system/lib/libc.so -> /apex/com.android.runtime/lib/bionic/libc.so
  • /system/lib/libm.so -> /apex/com.android.runtime/lib/bionic/libm.so
  • /system/lib/libdl.so -> /apex/com.android.runtime/lib/bionic/libdl.so
  • /system/bin/linker -> /apex/com.android.runtime/bin/linker

Te zmiany dotyczą również 64-bitowych wersji pliku, w którym pole lib/ zostało zastąpione elementem lib64/.

Aby zapewnić zgodność, dowiązania symboliczne są podane w starych ścieżkach. Na przykład /system/lib/libc.so jest dowiązaniem symbolicznym do: /apex/com.android.runtime/lib/bionic/libc.so. Usługa dlopen(“/system/lib/libc.so”) nadal działa, ale aplikacje zauważą różnicę, gdy spróbują sprawdzić załadowane biblioteki, odczytując /proc/self/maps lub w podobny sposób. Nie jest to normalne, ale odkryliśmy, że niektóre aplikacje robią to w ramach procesu ochrony przed hakerami. Jeśli tak, ścieżki /apex/… należy dodać jako prawidłowe ścieżki do plików Bionic.

Systemowe pliki binarne/biblioteki zmapowane na pamięć tylko do wykonywania

Począwszy od Androida 10 wykonywalne segmenty systemowych plików binarnych i bibliotek są mapowane w pamięć tylko do wykonania (nieczytelną) jako metodę wzmacniania zabezpieczeń przed atakami polegającymi na ponownym wykorzystaniu kodu. Jeśli aplikacja wykonuje operacje odczytu w segmentach pamięci oznaczonych jako tylko do wykonania – ze względu na błąd, lukę w zabezpieczeniach lub zamierzoną kontrolę pamięci – system wysyła do aplikacji sygnał SIGSEGV.

Aby określić, czy to działanie spowodowało awarię, sprawdź powiązany plik tombstone w programie /data/tombstones/. Awaria związana tylko z wykonaniem zawiera ten komunikat o przerwieniu:

Cause: execute-only (no-read) memory access error; likely due to data in .text.

Aby obejść ten problem i wykonywać takie operacje jak inspekcja pamięci, możesz oznaczyć segmenty tylko do wykonania jako do odczytu i wykonania, wywołując metodę mprotect(). Zdecydowanie zalecamy jednak, aby po zakończeniu tego procesu wrócić do ustawienia „Tylko do wykonywania”, ponieważ to ustawienie uprawnień dostępu zapewnia lepszą ochronę aplikacji i użytkowników.

Zabezpieczenia

Android 10 wprowadza opisane poniżej zmiany w zabezpieczeniach.

Domyślnie włączony protokół TLS 1.3

W Androidzie 10 i nowszych protokół TLS 1.3 jest domyślnie włączony we wszystkich połączeniach TLS. Oto kilka ważnych informacji o wdrażaniu TLS 1.3:

  • Nie można dostosować zestawów szyfrów TLS 1.3. Gdy jest włączony protokół TLS 1.3, obsługiwane pakiety szyfrów TLS 1.3 są zawsze włączone. Każda próba wyłączenia ich przez wywołanie metody setEnabledCipherSuites() jest ignorowana.
  • Gdy negocjowana jest wersja TLS 1.3, obiekty HandshakeCompletedListener są wywoływane przed dodaniem sesji do pamięci podręcznej sesji. (W TLS 1.2 i innych poprzednich wersjach obiekty te są wywoływane po dodaniu sesji do pamięci podręcznej sesji.
  • W niektórych sytuacjach, gdy instancje SSLEngine wysyłają błąd SSLHandshakeException w poprzednich wersjach Androida, na Androidzie 10 i nowszych wersjach systemu zamiast niego wyświetlają się SSLProtocolException.
  • Tryb 0-RTT nie jest obsługiwany.

W razie potrzeby możesz uzyskać numer SSLContext z wyłączonym protokołem TLS 1.3, wywołując metodę SSLContext.getInstance("TLSv1.2"). Możesz też włączać i wyłączać wersje protokołu dla poszczególnych połączeń, wywołując setEnabledProtocols() w odpowiednim obiekcie.

Certyfikaty podpisane przy użyciu SHA-1 nie są zaufane w TLS

W Androidzie 10 certyfikaty korzystające z algorytmu szyfrowania SHA-1 nie są zaufane w połączeniach TLS. Główne urzędy certyfikacji nie wydawały takiego certyfikatu od 2016 roku i nie są już zaufane w Chrome ani w innych popularnych przeglądarkach.

Każda próba nawiązania połączenia kończy się niepowodzeniem, jeśli połączenie dotyczy witryny, która przedstawi certyfikat za pomocą SHA-1.

Zmiany w działaniu i ulepszeniach pęku kluczy

Niektóre przeglądarki, takie jak Google Chrome, pozwalają użytkownikom wybrać certyfikat, gdy serwer TLS wysyła wiadomość z żądaniem certyfikatu w ramach uzgadniania połączenia TLS. Od Androida 10 obiekty KeyChain obsługują wydawców i parametry specyfikacji kluczy podczas wywoływania funkcji KeyChain.choosePrivateKeyAlias() w celu wyświetlania użytkownikom prośby o wybór certyfikatu. W szczególności nie zawiera ono opcji zgodnych ze specyfikacją serwera.

Jeśli nie są dostępne żadne certyfikaty do wyboru przez użytkownika, na przykład gdy żaden certyfikat nie jest zgodny ze specyfikacją serwera lub urządzenie nie ma zainstalowanych żadnych certyfikatów, prośba o wybór certyfikatu w ogóle się nie wyświetli.

Ponadto w Androidzie 10 i nowszych nie trzeba stosować blokady ekranu urządzenia, aby importować klucze lub certyfikaty CA do obiektu KeyChain.

Inne zmiany dotyczące TLS i kryptografii

W bibliotekach TLS i kryptografii wprowadziliśmy kilka drobnych zmian, które zaczną obowiązywać w Androidzie 10:

  • Mechanizmy AES/GCM/NoPadding i ChaCha20/Poly1305/NoPadding zwracają bardziej dokładne rozmiary bufora z poziomu getOutputSize().
  • Zestaw szyfrów TLS_FALLBACK_SCSV jest pomijany w przypadku prób nawiązania połączenia z protokołem maksymalnego TLS 1.2 lub nowszym. Ze względu na usprawnienia implementacji serwera TLS nie zalecamy korzystania z zewnętrznej kreacji zastępczej TLS. Zamiast tego zalecamy negocjowanie wersji TLS.
  • ChaCha20-Poly1305 to alias dla ChaCha20/Poly1305/NoPadding.
  • Nazwy hostów z kropkami na końcu nie są uznawane za prawidłowe nazwy hostów SNI.
  • Rozszerzenie obsługiwane_signature_algorithms w CertificateRequest jest respektowane w przypadku wyboru klucza podpisywania na potrzeby odpowiedzi certyfikatu.
  • Nieprzezroczyste klucze podpisywania, na przykład z magazynu kluczy Androida, mogą być używane z podpisami RSA-PSS w protokole TLS.

Transmisje Wi-Fi Direct

Na Androidzie 10 te komunikaty związane z Wi-Fi Direct nie są przyklejone:

Jeśli Twoja aplikacja polegała na odbieraniu tych komunikatów podczas rejestracji, ponieważ były one trwałe, użyj odpowiedniej metody get() przy inicjowaniu, aby uzyskać informacje.

Funkcje Wi-Fi Aware

Android 10 obsługuje ułatwienia tworzenia gniazd TCP/UDP za pomocą ścieżek danych Aware Aware. Aby utworzyć gniazdo TCP/UDP łączące się z ServerSocket, urządzenie klienckie musi znać adres IPv6 i port serwera. Wcześniej trzeba było je przekazywać poza pasmem, na przykład przez przesyłanie komunikatów BT lub Wi-Fi Aware w warstwie 2, albo wykryto w nim za pomocą innych protokołów, takich jak mDNS. W Androidzie 10 informacje można przekazywać w ramach konfiguracji sieci.

Serwer może wykonać jedną z tych czynności:

  • Zainicjuj ServerSocket i ustaw lub uzyskaj port, który ma być używany.
  • Podaj informacje o porcie jako część żądania sieciowego Wi-Fi Aware.

Poniższy przykładowy kod pokazuje, jak określić informacje o porcie w żądaniu sieciowym:

Kotlin

val ss = ServerSocket()
val ns = WifiAwareNetworkSpecifier.Builder(discoverySession, peerHandle)
  .setPskPassphrase("some-password")
  .setPort(ss.localPort)
  .build()

val myNetworkRequest = NetworkRequest.Builder()
  .addTransportType(NetworkCapabilities.TRANSPORT_WIFI_AWARE)
  .setNetworkSpecifier(ns)
  .build()

Java

ServerSocket ss = new ServerSocket();
WifiAwareNetworkSpecifier ns = new WifiAwareNetworkSpecifier
  .Builder(discoverySession, peerHandle)
  .setPskPassphrase(“some-password”)
  .setPort(ss.getLocalPort())
  .build();

NetworkRequest myNetworkRequest = new NetworkRequest.Builder()
  .addTransportType(NetworkCapabilities.TRANSPORT_WIFI_AWARE)
  .setNetworkSpecifier(ns)
  .build();

Następnie klient wykonuje żądanie sieciowe związane z Wi-Fi Aware, aby uzyskać adres IPv6 i port udostępniony przez serwer:

Kotlin


val callback = object : ConnectivityManager.NetworkCallback() {
  override fun onAvailable(network: Network) {
    ...
  }
  
  override fun onLinkPropertiesChanged(network: Network,
      linkProperties: LinkProperties) {
    ...
  }

  override fun onCapabilitiesChanged(network: Network,
      networkCapabilities: NetworkCapabilities) {
    ...
    val ti = networkCapabilities.transportInfo
    if (ti is WifiAwareNetworkInfo) {
       val peerAddress = ti.peerIpv6Addr
       val peerPort = ti.port
    }
  }
  override fun onLost(network: Network) {
    ...
  }
};

connMgr.requestNetwork(networkRequest, callback)

Java

callback = new ConnectivityManager.NetworkCallback() {
  @Override
  public void onAvailable(Network network) {
    ...
  }
  @Override
  public void onLinkPropertiesChanged(Network network,
      LinkProperties linkProperties) {
    ...
  }
  @Override
  public void onCapabilitiesChanged(Network network,
      NetworkCapabilities networkCapabilities) {
    ...
    TransportInfo ti = networkCapabilities.getTransportInfo();
    if (ti instanceof WifiAwareNetworkInfo) {
       WifiAwareNetworkInfo info = (WifiAwareNetworkInfo) ti;
       Inet6Address peerAddress = info.getPeerIpv6Addr();
       int peerPort = info.getPort();
    }
  }
  @Override
  public void onLost(Network network) {
    ...
  }
};

connMgr.requestNetwork(networkRequest, callback);

SYSTEM_ALERT_WINDOW na urządzeniach Go

Aplikacje działające na urządzeniach z Androidem 10 (wersja Go) nie mogą otrzymać uprawnienia SYSTEM_ALERT_WINDOW. Wynika to z tego, że rysowanie okien typu nakładek wykorzystuje nadmierną ilość pamięci, co jest szczególnie szkodliwe dla urządzeń z Androidem, które mają mało pamięci.

Jeśli aplikacja działająca na urządzeniu w wersji Go z Androidem 9 lub starszym otrzyma uprawnienie SYSTEM_ALERT_WINDOW, zachowa je nawet wtedy, gdy urządzenie zostanie zaktualizowane do Androida 10. Jednak aplikacjom, które nie mają jeszcze tego uprawnienia, nie można przyznać po uaktualnieniu urządzenia.

Jeśli aplikacja na urządzeniu Go wysyła intencję z działaniem ACTION_MANAGE_OVERLAY_PERMISSION, system automatycznie odrzuca żądanie i przekierowuje użytkownika do ekranu Ustawienia z informacją, że uprawnienia są niedozwolone, ponieważ spowalniają urządzenie. Jeśli aplikacja na urządzeniu Go wywołuje metodę Settings.canDrawOverlays(), ta metoda zawsze zwraca wartość fałsz. Te ograniczenia nie dotyczą aplikacji, które otrzymały uprawnienie SYSTEM_ALERT_WINDOW przed aktualizacją urządzenia do Androida 10.

Ostrzeżenia dotyczące aplikacji kierowanych na starsze wersje Androida

Urządzenia z Androidem 10 lub nowszym ostrzegają użytkowników przy pierwszym uruchomieniu aplikacji kierowanej na Androida 5.1 (poziom interfejsu API 22) lub starszego. Jeśli aplikacja wymaga od użytkownika przyznania uprawnień, użytkownik może też dostosować uprawnienia aplikacji, zanim zostanie ona uruchomiona po raz pierwszy.

Ze względu na wymagania dotyczące docelowego interfejsu API Google Play użytkownik widzi te ostrzeżenia tylko wtedy, gdy uruchamia aplikację, która nie była ostatnio aktualizowana. W przypadku aplikacji rozpowszechnianych w innych sklepach zaczną obowiązywać podobne wymagania dotyczące docelowych interfejsów API w 2019 roku. Więcej informacji o tych wymaganiach znajdziesz w artykule Rozwijanie wymagań dotyczących docelowego poziomu interfejsu API w 2019 roku.

Usunięto zestawy szyfrów SHA-2 CBC

Usunęliśmy z platformy te zestawy szyfrów SHA-2 CBC:

  • TLS_RSA_WITH_AES_128_CBC_SHA256
  • TLS_RSA_WITH_AES_256_CBC_SHA256
  • TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
  • TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
  • TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
  • TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384

Te zestawy szyfrów są mniej bezpieczne niż podobne zestawy szyfrów, które korzystają z GCM, a większość serwerów obsługuje zarówno wersje GCM, jak i CBC albo nie obsługuje żadnego z nich.

Transmisja danych w aplikacjach

Android 10 wprowadza te zmiany w działaniu związane z korzystaniem z aplikacji:

  • Lepsze wykorzystanie aplikacji ze statystykami użytkowania – aplikacja na ekranie lub obraz, Dodatkowo Android 10 poprawnie śledzi korzystanie z aplikacji błyskawicznych.

  • Skala szarości dla poszczególnych aplikacji - tryb szarości – w zależności od aplikacji.

  • Stan rozpraszania uwagi aplikacji- stan aplikacji

  • Zawieszenie i odtwarzanie – w Androidzie nie można odtwarzać dźwięku.

Zmiany połączeń HTTPS

Jeśli aplikacja działająca na Androidzie 10 przekazuje null do setSSLSocketFactory(), wystąpi IllegalArgumentException. W poprzednich wersjach przekazywanie null do setSSLSocketFactory() dawało taki sam efekt jak przekazanie danych w bieżącej fabryce domyślnej.

Biblioteka android.preference została wycofana

W Androidzie 10 biblioteka android.preference jest wycofana. Deweloperzy powinni zamiast tego korzystać z biblioteki preferencji AndroidaX, która jest częścią Androida Jetpacka. Więcej materiałów ułatwiających migrację i programowanie znajdziesz w zaktualizowanym przewodniku po ustawieniach wraz z naszą publiczną przykładową aplikacją i dokumentacją referencyjną.

Zmiany w bibliotece narzędzia do obsługi plików ZIP

Android 10 wprowadza poniższe zmiany w klasach w pakiecie java.util.zip, który obsługuje pliki ZIP. Te zmiany sprawią, że działanie biblioteki będzie bardziej spójne na Androidzie i innych platformach korzystających z java.util.zip.

Sztuczne

W poprzednich wersjach niektóre metody klasy Inflater zwracały działanie IllegalStateException, jeśli zostały wywołane po wywołaniu end(). W Androidzie 10 te metody zgłaszają NullPointerException.

Plik ZIP

W Androidzie 10 i nowszych konstruktor obiektu ZipFile, który przyjmuje argumenty typu File, int i Charset nie zgłasza ZipException, jeśli dostarczony plik ZIP nie zawiera żadnych plików.

Strumień danych wyjściowych Zip

W Androidzie 10 i nowszych metoda finish() w ZipOutputStream nie zgłasza ZipException, jeśli próbuje zapisać strumień wyjściowy dla pliku ZIP, który nie zawiera żadnych plików.

Zmiany w kamerze

Wiele aplikacji korzystających z aparatu zakłada, że jeśli urządzenie jest w orientacji pionowej, jest ono również w orientacji pionowej, co opisaliśmy w sekcji Orientacja aparatu. W przeszłości było to bezpieczne założenie, ale to się zmieniło w miarę zwiększania liczby dostępnych formatów, takich jak urządzenia składane. W przypadku tych urządzeń może to spowodować nieprawidłowe obrót lub przeskalowanie obrazu w wizjerze aparatu (albo jedno i drugie).

Aplikacje kierowane na interfejs API na poziomie 24 lub wyższym powinny wyraźnie ustawić parametr android:resizeableActivity i zapewnić funkcje niezbędne do obsługi operacji w wielu oknach.

Śledzenie wykorzystania baterii

Począwszy od Androida 10 SystemHealthManager resetuje statystyki wykorzystania baterii za każdym razem, gdy urządzenie jest odłączone od zasilania po dużej fakcie ładowania. Ogólnie rzecz biorąc, najważniejsze obciążenie to:

Przed Androidem 10 statystyki wykorzystania baterii są resetowane za każdym razem, gdy urządzenie jest odłączone od zasilania, bez względu na to, jak niewielka zmiana nastąpiła w poziomie baterii.

Wycofanie Android Beam

W Androidzie 10 oficjalnie wycofujemy Android Beam, starszą funkcję, która umożliwia udostępnianie danych między urządzeniami za pomocą komunikacji Near Field Communication (NFC). Wycofujemy też kilka powiązanych z nimi interfejsów API NFC. Funkcja Android Beam pozostaje opcjonalnie dostępna dla producentów urządzeń, którzy chcą z niej korzystać. Nie jest ona już jednak w fazie rozwoju. Android będzie nadal obsługiwać inne interfejsy API i funkcje NFC, ale przypadki użycia takie jak odczyt z tagów i płatności będą nadal działać zgodnie z oczekiwaniami.

Zmiana zachowania funkcji java.math.BigDecimal.stripTrailingZeros()

BigDecimal.stripTrailingZeros() nie zachowuje już zera na końcu w szczególnym przypadku, gdy wartość wejściowa wynosi 0.

Zmiany w działaniu java.util.regex.Matcher i wzorca

Wynik funkcji split() został zmieniony tak, aby nie zaczynał się już pustym elementem String(""), gdy na początku danych wejściowych występuje dopasowanie o zerowej szerokości. Dotyczy to również usługi String.split(). Na przykład funkcja "x".split("") zwraca teraz {"x"}, podczas gdy w starszych wersjach Androida wcześniej zwracała wartość {"", "x"}. "aardvark".split("(?=a)" zwraca teraz {"a", "ardv", "ark"} zamiast {"", "a", "ardv", "ark"}.

Ulepszyliśmy też sposób działania wyjątków w przypadku nieprawidłowych argumentów:

  • appendReplacement(StringBuffer, String) zwraca teraz IllegalArgumentException zamiast IndexOutOfBoundsException, jeśli zamiennik String kończy się pojedynczym ukośnikiem lewym, co jest niedozwolone. Ten sam wyjątek jest teraz zgłaszany, jeśli element zastępczy String kończy się znakiem $. Wcześniej w takiej sytuacji nie został zgłoszony żaden wyjątek.
  • replaceFirst(null) nie wywołuje już wywołania reset() na Matcher, jeśli zwróci błąd NullPointerException. NullPointerException jest też odrzucany, gdy nie ma dopasowań. Wcześniej był on odrzucany tylko wtedy, gdy udało się dopasować grę.
  • start(int group), end(int group) i group(int group) zgłaszają teraz bardziej ogólne IndexOutOfBoundsException, jeśli indeks grupy jest poza zakresem. Wcześniej te metody zwracały żądanie ArrayIndexOutOfBoundsException.

Domyślny kąt elementu GradientDrawable to teraz TOP_BOTTOM

Jeśli w Androidzie 10 zdefiniujesz obiekt GradientDrawable w pliku XML, ale nie podasz pomiaru kąta, orientacja gradientu będzie domyślnie ustawiona na TOP_BOTTOM. To zmiana w porównaniu z poprzednimi wersjami Androida, gdzie wartość domyślna to LEFT_RIGHT.

Aby obejść ten problem, po zaktualizowaniu pakietu AAPT2 do najnowszej wersji narzędzie ustawi kąt w starszych aplikacjach na 0, jeśli nie podasz pomiaru kąta.

Logowanie serializowanych obiektów przy użyciu domyślnego identyfikatora SUID

Począwszy od Androida 7.0 (poziom interfejsu API 24) platforma wprowadziła poprawkę domyślnej wartości serialVersionUID dla serializowalnych obiektów. Ta poprawka nie ma wpływu na aplikacje kierowane na interfejs API na poziomie 23 lub niższym.

Począwszy od Androida 10, jeśli aplikacja jest kierowana na interfejs API na poziomie 23 lub niższym i korzysta ze starego, nieprawidłowego, domyślnego elementu serialVersionUID, system rejestruje ostrzeżenie i zaproponuje poprawkę kodu.

System rejestruje ostrzeżenie, jeśli są spełnione wszystkie te warunki:

  • Aplikacja jest kierowana na interfejs API na poziomie 23 lub niższym.
  • Klasa jest zserializowana.
  • Klasa zserializowana używa domyślnego serialVersionUID, zamiast jednoznacznie ustawiać serialVersionUID.
  • Domyślna wartość serialVersionUID różni się od serialVersionUID, gdy aplikacja jest kierowana na interfejs API na poziomie 24 lub wyższym.

To ostrzeżenie jest logowane raz dla każdej klasy, której dotyczy problem. Komunikat z ostrzeżeniem zawiera sugerowaną poprawkę, czyli ustawienie w polu serialVersionUID wartości domyślnej, która będzie obliczana, jeśli aplikacja jest kierowana na interfejs API na poziomie 24 lub wyższym. Korzystając z tej poprawki, masz pewność, że jeśli obiekt z tej klasy jest zserializowany w aplikacji kierowanej na interfejs API na poziomie 23 lub niższym, obiekt będzie poprawnie odczytywany przez aplikacje kierowane na wersję 24 lub nowszą, i odwrotnie.

Zmiany w java.io.FileChannel.map()

Od Androida 10 usługa FileChannel.map() nie jest obsługiwana w przypadku plików niestandardowych (np. /dev/zero), których rozmiaru nie można zmienić za pomocą truncate(). Poprzednie wersje Androida pomijały błąd zwracany przez funkcję truncate(), ale Android 10 zgłaszał wyjątek IOException. Aby zacząć korzystać ze starego sposobu, użyj kodu natywnego.