Zmiany w działaniu: wszystkie aplikacje

Android 10 zawiera zmiany zachowania, które mogą mieć wpływ na Twoją aplikację. Zmiany wymienione na tej stronie mają zastosowanie do aplikacji, gdy jest ona uruchamiana na Androidzie 10, niezależnie od jej targetSdkVersion. Aby zapewnić prawidłowe działanie aplikacji po wprowadzeniu tych zmian, przetestuj ją i w razie potrzeby zmodyfikuj.

Jeśli wartość targetSdkVersion Twojej aplikacji wynosi 29 lub jest wyższa, musisz też uwzględnić dodatkowe zmiany. Szczegółowe informacje znajdziesz w zmianach zachowania aplikacji kierowanych na 29 lat.

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
  • Rozpoczęcie aktywności w tle
  • Informacje o powiązaniach z kontaktami
  • losowanie adresów MAC.
  • Metadane aparatu
  • Model uprawnień

Te zmiany dotyczą wszystkich aplikacji i zwiększają prywatność użytkowników. Więcej informacji o tym, jak wspierać te zmiany, znajdziesz na stronie Zmiany dotyczące prywatności.

Ograniczenia interfejsu innego niż SDK

Aby zapewnić stabilność i zgodność aplikacji, platforma zaczęła ograniczać interfejsy spoza pakietu SDK, których Twoja aplikacja może używać w Androidzie 9 (poziom API 28). Android 10 zawiera zaktualizowane listy ograniczonych interfejsów spoza pakietu SDK, które powstały na podstawie współpracy z deweloperami Androida i ostatnich testów wewnętrznych. Chcemy się upewnić, że dostępne są publiczne alternatywy, zanim zaczniemy ograniczać interfejsy inne niż SDK.

Jeśli nie będziesz kierować 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 pakietu SDK (w zależności od docelowego poziomu interfejsu API aplikacji), ale korzystanie z metod lub pól spoza pakietu 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ć, przetestując aplikację. Jeśli Twoja aplikacja korzysta z interfejsów spoza pakietu SDK, zaplanuj migrację na alternatywne pakiety SDK. Zdajemy sobie jednak sprawę, że w niektórych przypadkach interfejsy inne niż SDK mogą być przydatne. Jeśli nie możesz znaleźć alternatywy dla interfejsu spoza pakietu SDK, który jest używany w funkcji Twojej aplikacji, poproś o nowy publiczny interfejs API.

Więcej informacji znajdziesz w artykule Aktualizacje ograniczeń interfejsów innych niż SDK w Androidzie 10 oraz Ograniczenia interfejsów innych niż SDK.

Nawigacja przy użyciu gestów

Począwszy od Androida 10 użytkownicy mogą włączyć nawigację za pomocą gestów na całym urządzeniu. Jeśli użytkownik włączy nawigację za pomocą gestów, wpłynie to na wszystkie aplikacje na urządzeniu, niezależnie od tego, czy aplikacja jest kierowana na interfejs API na poziomie 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 aplikacja była zgodna z nawigacją za pomocą gestów, rozciągnij zawartość aplikacji od krawędzi do krawędzi i odpowiednio obsłuż sprzeczne gesty. Więcej informacji znajdziesz w dokumentacji dotyczącej nawigacji za pomocą gestów.

NDK

Android 10 zawiera te zmiany w NDK:

Udostępnione obiekty nie mogą zawierać przemieszczeń tekstu.

Android 6.0 (poziom interfejsu API 23) nie zezwala na przenoszenie tekstu w wspólnych obiektach. Kod musi być wczytany w postaci oryginalnej i nie może być modyfikowany. Ta zmiana wydłuży czas wczytywania aplikacji i zwiększy bezpieczeństwo.

SELinux wymusza to ograniczenie w aplikacjach kierowanych na Androida 10 lub nowszego. Jeśli te aplikacje nadal będą używać udostępnionych obiektów zawierających przeniesienia tekstu, istnieje duże ryzyko, że ulegną one uszkodzeniu.

Zmiany w bibliotekach Bionic i ścieżkach dynamicznego linkera

Począwszy od Androida 10 kilka ścieżek to linki symboliczne zamiast zwykłych plików. Aplikacje, które korzystały ze ścieżek jako zwykłych plików, mogą przestać działać:

  • /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

Zmiany te dotyczą również wersji 64-bitowych pliku, w których lib/ zostało zastąpione przez lib64/.

Ze względu na zgodność symboliczne linki są udostępniane na starych ścieżkach. Na przykład /system/lib/libc.so jest dowiązaniem symbolicznym do: /apex/com.android.runtime/lib/bionic/libc.so. W rezultacie dlopen(“/system/lib/libc.so”) nadal działa, ale aplikacje zauważą różnicę, gdy spróbują zbadać załadowane biblioteki, odczytując /proc/self/maps lub podobne dane. Nie jest to typowe, ale okazało się, że niektóre aplikacje robią to w ramach procesu zapobiegania włamaniom. Jeśli tak, ścieżki /apex/… należy dodać jako prawidłowe ścieżki do plików Bionic.

pliki binarne/biblioteki systemowe 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 Twoja aplikacja wykonuje operacje odczytu w segmentach pamięci oznaczonych jako „tylko do wykonania” (z powodu błędu, luki w zabezpieczeniach lub celowego sprawdzenia pamięci), system wysyła do niej sygnał SIGSEGV.

Aby sprawdzić, czy to zachowanie spowodowało awarię, możesz przejrzeć powiązany plik tombstone w folderze /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 wykonać operacje takie jak inspekcja pamięci, możesz oznaczyć segmenty tylko do wykonania jako odczyt + wykonanie, wywołując funkcję mprotect(). Zalecamy jednak, aby później zmienić to ustawienie z powrotem na „Tylko wykonywanie”, ponieważ to ustawienie uprawnień dostępu zapewnia lepszą ochronę aplikacji i użytkowników.

Bezpieczeństwo

Android 10 zawiera te zmiany dotyczące zabezpieczeń:

TLS 1.3 jest domyślnie włączony

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

  • Zestawy szyfrów TLS 1.3 nie mogą być dostosowywane. Obsługiwane zestawy szyfrów TLS 1.3 są zawsze włączone, gdy włączony jest TLS 1.3. Każda próba ich wyłączenia przez wywołanie funkcji setEnabledCipherSuites() zostanie zignorowana.
  • Podczas negocjowania 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 w poprzednich wersjach Androida wywołują błąd SSLHandshakeException, w Androidzie 10 i nowszych instancje te wywołują błąd SSLProtocolException.
  • Tryb 0-RTT nie jest obsługiwany.

Jeśli chcesz, możesz uzyskać SSLContext z wyłączonym protokołem TLS 1.3, wykonując wywołanie SSLContext.getInstance("TLSv1.2"). Wersje protokołów możesz też włączać i wyłączać w poszczególnych połączeniach, wywołując setEnabledProtocols() w odpowiednim obiekcie.

Certyfikaty podpisane za pomocą algorytmu SHA-1 nie są zaufane w TLS

W Androidzie 10 certyfikaty, które używają algorytmu szyfrowania SHA-1, nie są zaufane w przypadku połączeń 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 połączenia kończy się niepowodzeniem, jeśli połączenie jest z witryną, która przedstawia certyfikat z wykorzystaniem SHA-1.

Zmiany i ulepszenia dotyczące KeyChain

Niektóre przeglądarki, takie jak Google Chrome, umożliwiają użytkownikom wybranie certyfikatu, gdy serwer TLS wysyła wiadomość z żądaniem certyfikatu w ramach uzgadniania połączenia TLS. Od Androida 10 obiekty KeyChain uwzględniają parametry specyfikacji wydawców i kluczy podczas wywoływania KeyChain.choosePrivateKeyAlias(), aby wyświetlić użytkownikom prośbę o wybranie certyfikatu. W tym prompt nie ma opcji, które nie są zgodne ze specyfikacją serwera.

Jeśli nie ma certyfikatów, które użytkownik może wybrać (np. gdy żaden z nich nie pasuje do specyfikacji serwera lub na urządzeniu nie ma zainstalowanych żadnych certyfikatów), prośba o wybór certyfikatu w ogóle się nie wyświetli.

Ponadto w Androidzie 10 lub nowszym nie trzeba blokować ekranu urządzenia, aby zaimportować klucze lub certyfikaty urzędu certyfikacji 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 ulepszenia w implementacjach serwerów TLS nie zalecamy korzystania z zewnętrznego mechanizmu zastępczego TLS. Zamiast tego zalecamy poleganie na negocjacjach wersji TLS.
  • ChaCha20-Poly1305 to alias nazwy ChaCha20/Poly1305/NoPadding.
  • Nazwy hostów z kropkami na końcu nie są uznawane za prawidłowe nazwy hostów SNI.
  • Podczas wybierania klucza podpisywania odpowiedzi certyfikatu uwzględniane jest rozszerzenie supported_signature_algorithms w sekcji CertificateRequest.
  • Nieprzezroczyste klucze podpisywania, takie jak te z Keystore na Androida, można używać z podpisami RSA-PSS w TLS.

Transmisje Wi-Fi Direct

Na Androidzie 10 te transmisje związane z Wi-Fi Direct nie są trwałe:

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 umożliwia ułatwione tworzenie gniazda TCP/UDP za pomocą ścieżek danych Wi-Fi Aware. Aby utworzyć gniazdo TCP/UDP łączące się z ServerSocket, urządzenie klienta 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:

  • Inicjuj ServerSocket i ustaw lub pobierz port do użycia.
  • Określ informacje o porcie w ramach żądania sieci Wi-Fi Aware.

Poniższy przykładowy kod pokazuje, jak podać informacje o porcie w żądaniu sieci:

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. Dzieje się tak, ponieważ 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 z Androidem 9 lub starszym otrzyma uprawnienie SYSTEM_ALERT_WINDOW, to uprawnienie pozostanie przypisane do aplikacji nawet wtedy, gdy urządzenie zostanie zaktualizowane do Androida 10. Jednak aplikacji, które nie mają tego uprawnienia, nie można go 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 przenosi użytkownika na ekran Ustawienia, na którym informuje, że uprawnienie nie jest dozwolone, ponieważ spowalnia urządzenie. Jeśli aplikacja na urządzeniu Go wywołuje funkcję Settings.canDrawOverlays(), metoda zawsze zwraca wartość „fałsz”. Ponownie przypominamy, że te ograniczenia nie dotyczą aplikacji, które otrzymały uprawnienie SYSTEM_ALERT_WINDOW przed uaktualnieniem urządzenia do Androida 10.

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

Użytkownicy urządzeń z Androidem 10 lub nowszym otrzymują ostrzeżenie 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 Google Play dotyczące docelowego poziomu interfejsu API użytkownik widzi te ostrzeżenia tylko wtedy, gdy uruchomi aplikację, która nie była ostatnio aktualizowana. W przypadku aplikacji rozpowszechnianych w innych sklepach podobne wymagania dotyczące docelowego interfejsu API zaczną obowiązywać w 2019 r. Więcej informacji o tych wymaganiach znajdziesz w artykule Rozwijanie wymagań dotyczących docelowego poziomu interfejsu API w 2019 roku.

Usunięcie zestawów szyfrów SHA-2 CBC

Z platformy zostały usunięte te zestawy szyfrów CBC SHA-2:

  • 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:

  • Ulepszenia dotyczące korzystania z aplikacji UsageStats – Android 10 dokładnie śledzi korzystanie z aplikacji za pomocą UsageStats, gdy aplikacje są używane w trybie podzielonego ekranu lub obrazu w obrazie. Dodatkowo Android 10 poprawnie śledzi korzystanie z aplikacji błyskawicznych.

  • Tryb szarości dla poszczególnych aplikacji – Android 10 może ustawiać tryb wyświetlania w szarościach dla poszczególnych aplikacji.

  • Stan „rozpraszania uwagi” dla poszczególnych aplikacji – w Androidzie 10 można ustawić, aby wybrane aplikacje były w stanie „rozpraszania uwagi”, w którym ich powiadomienia są tłumione i nie pojawiają się jako sugerowane aplikacje.

  • Konto

Zmiany połączeń HTTPS

Jeśli aplikacja na Androidzie 10 przekaże null do setSSLSocketFactory(), nastąpi IllegalArgumentException. W poprzednich wersjach przekazanie argumentu null do funkcji setSSLSocketFactory() miało taki sam efekt jak przekazanie bieżącej fabrykacji domyślnej.

Biblioteka android.preference została wycofana

Biblioteka android.preference została wycofana w Androidzie 10. Deweloperzy powinni zamiast tego używać biblioteki preferencji AndroidX, która jest częścią Jetpacka Androida. Aby uzyskać dodatkowe materiały pomocne w migracji i rozwijaniu aplikacji, zapoznaj się z aktualizowanym przewodnikiem po ustawieniach, publiczną aplikacją przykładową oraz dokumentacją referencyjną.

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

Android 10 wprowadza następujące zmiany w klasach w pakiecie java.util.zip, który obsługuje pliki ZIP. Dzięki tym zmianom działanie biblioteki jest bardziej spójne na Androidzie i innych platformach, które korzystają z java.util.zip.

Inflater

We wcześniejszych wersjach niektóre metody klasy Inflater wywoływały błąd IllegalStateException, jeśli były wywoływane po wywołaniu metody end(). W Androidzie 10 te metody zwracają zamiast tego kod błędu NullPointerException.

ZipFile

W Androidzie 10 i nowszych konstruktor klasy ZipFile, który przyjmuje argumenty typu File, intCharset, nie zgłasza wyjątku ZipException, jeśli podany plik ZIP nie zawiera żadnych plików.

ZipOutputStream

W Androidzie 10 i nowszych metoda finish()ZipOutputStream nie powoduje błęduZipException, jeśli próbuje zapisać strumień wyjściowy do pliku ZIP, który nie zawiera żadnych plików.

Zmiany w aparacie

Wiele aplikacji korzystających z kamery zakłada, że jeśli urządzenie jest w orientacji poziomej, to fizyczne urządzenie jest też w orientacji poziomej, jak opisano w sekcji Orientacja kamery. W przeszłości było to bezpieczne założenie, ale zmieniło się to wraz z rozszerzeniem dostępnych formatów, takich jak składane urządzenia. W przypadku tych urządzeń może to spowodować nieprawidłowe obrócenie lub przeskalowanie wizjera aparatu (albo jedno i drugie).

Aplikacje kierowane na interfejs API na poziomie 24 lub wyższym powinny wyraźnie ustawić android:resizeableActivity i zapewnić niezbędne funkcje do obsługi działania 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, główne zdarzenie ładowania to: urządzenie zostało w pełni naładowane lub urządzenie przeszło z stanu „głównie puste” do „głównie naładowane”.

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, czyli starszą funkcję umożliwiającą 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. Android Beam jest nadal opcjonalnie dostępny dla partnerów będących producentami urządzeń, którzy chcą z niego korzystać, ale nie jest już aktywnie rozwijany. 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 działania 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 pakietu java.util.regex.Matcher i Pattern

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ż 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"}.

Poprawiono też działanie 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 zastępowana wartość String kończy się na $. Wcześniej w tym scenariuszu nie było zgłaszanych wyjątków.
  • Funkcja replaceFirst(null) nie wywołuje już funkcji reset() w przypadku obiektu Matcher, jeśli powoduje ona błąd NullPointerException. Wyjątek NullPointerException jest teraz również zgłaszany, gdy nie ma dopasowania. Wcześniej wyjątek był zgłaszany tylko w przypadku dopasowania.
  • Funkcje start(int group), end(int group) i group(int group) zgłaszają teraz bardziej ogólny błąd IndexOutOfBoundsException, jeśli indeks grupy jest poza zakresem. Wcześniej te metody zwracały żądanie ArrayIndexOutOfBoundsException.

Domyślnym kątem dla GradientDrawable jest teraz TOP_BOTTOM

W Androidzie 10, jeśli zdefiniujesz element GradientDrawable w pliku XML i nie podasz pomiaru kąta, orientacja gradientu zostanie domyślnie ustawiona na TOP_BOTTOM. Jest to zmiana w porównaniu z poprzednimi wersjami Androida, w których domyślnie była używana wartość LEFT_RIGHT.

Jeśli zaktualizujesz narzędzie do najnowszej wersji AAPT2, w przypadku starszych aplikacji, w których nie określono pomiaru kąta, narzędzie ustawia wartość 0.

Logowanie dla serializowanych obiektów przy użyciu domyślnego 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 dotyczyła aplikacji kierowanych na poziom interfejsu API 23 lub niższego.

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.

W szczególności 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 serializowana.
  • Klasa zserializowana używa domyślnego serialVersionUID, zamiast jednoznacznie ustawiać serialVersionUID.
  • Domyślna wartość serialVersionUID różni się od serialVersionUID, jeśli aplikacja jest kierowana na interfejs API na poziomie 24 lub wyższym.

To ostrzeżenie jest rejestrowane raz w przypadku każdej klasy, której dotyczy. Wiadomość ostrzegawcza zawiera sugerowane rozwiązanie, które polega na jawnym ustawieniu wartości serialVersionUID na wartość domyślną, która zostałaby obliczona, gdyby aplikacja była kierowana na interfejs API na poziomie 24 lub wyższym. Dzięki tej poprawce możesz mieć pewność, że jeśli obiekt z tej klasy zostanie zserializowany w aplikacji kierowanej na interfejs API na poziomie 23 lub niższym, będzie on prawidłowo odczytywany przez aplikacje kierowane na interfejs API na poziomie 24 lub wyższym 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(). W poprzednich wersjach Androida errno zwracany przez funkcję truncate() był ignorowany, ale Android 10 zgłasza wyjątek IOException. Aby zacząć korzystać ze starego sposobu, użyj kodu natywnego.