Zmiany w działaniu: wszystkie aplikacje

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

Jeśli wartość targetSdkVersion Twojej aplikacji to 29 lub więcej, musisz też obsługiwać dodatkowe zmiany. Aby dowiedzieć się więcej, przeczytaj artykuł o zmianach w działaniu aplikacji kierowanych na wersję 29.

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

  • Dostęp w tle do lokalizacji urządzenia
  • Rozpoczęcie aktywności w tle
  • informacje o powiązaniach kontaktów,
  • Randomizacja adresu MAC
  • Metadane aparatu
  • Model uprawnień

Te zmiany dotyczą wszystkich aplikacji i zwiększają prywatność użytkowników. Aby dowiedzieć się więcej o tym, jak dostosować się do tych zmian, wejdź na stronę Zmiany dotyczące prywatności.

Ograniczenia interfejsów innych niż SDK

Aby zapewnić stabilność i zgodność aplikacji, platforma zaczęła ograniczać interfejsy inne niż SDK, których aplikacja może używać w Androidzie 9 (poziom API 28). Android 10 zawiera zaktualizowane listy ograniczonych interfejsów innych niż SDK, które powstały we współpracy z programistami aplikacji na Androida oraz na podstawie najnowszych testów wewnętrznych. Naszym celem jest zapewnienie, że publiczne alternatywy będą dostępne, zanim ograniczymy 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 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 używa interfejsów innych niż SDK, możesz ją przetestować, aby to sprawdzić. Jeśli Twoja aplikacja korzysta z interfejsów innych niż SDK, zacznij planować migrację do alternatywnych rozwiązań SDK. Rozumiemy jednak, że niektóre aplikacje mają uzasadnione przypadki użycia interfejsów spoza pakietu SDK. Jeśli nie możesz znaleźć alternatywy dla interfejsu spoza pakietu SDK w przypadku funkcji w aplikacji, poproś o nowy publiczny interfejs API.

Więcej informacji znajdziesz w artykułach Aktualizacje ograniczeń interfejsów innych niż SDK w Androidzie 10 i Ograniczenia interfejsów innych niż SDK.

Nawigacja przy użyciu gestów

Od Androida 10 użytkownicy mogą włączyć nawigację przy użyciu gestów na całym 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ą one kierowane na interfejs API na poziomie 29. Jeśli na przykład użytkownik przesunie palcem od krawędzi ekranu, system zinterpretuje ten gest jako przechodzenie wstecz, chyba że aplikacja zastąpi ten gest w przypadku niektórych części ekranu.

Aby aplikacja była zgodna z nawigacją przy użyciu gestów, musisz rozszerzyć jej zawartość od krawędzi do krawędzi i odpowiednio obsługiwać sprzeczne gesty. Więcej informacji znajdziesz w dokumentacji dotyczącej nawigacji przy użyciu gestów.

NDK

Android 10 wprowadza te zmiany w NDK.

Obiekty udostępnione nie mogą zawierać przeniesień tekstu

Android 6.0 (poziom interfejsu API 23) nie zezwala na używanie relokacji tekstu w obiektach udostępnionych. Kod musi być wczytywany w niezmienionej postaci i nie wolno go modyfikować. Ta zmiana poprawia czas wczytywania aplikacji i bezpieczeństwo.

SELinux egzekwuje to ograniczenie w przypadku aplikacji kierowanych na Androida 10 lub nowszego. Jeśli te aplikacje będą nadal używać obiektów współdzielonych, które zawierają relokacje tekstu, istnieje duże ryzyko, że przestaną działać.

Zmiany w bibliotekach Bionic i ścieżkach dynamicznego linkera

Począwszy od Androida 10, kilka ścieżek to łącza symboliczne, a nie zwykłe pliki. Aplikacje, które korzystają ze ścieżek będących zwykłymi plikami, 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

Te zmiany dotyczą też 64-bitowych wersji pliku, w których lib/ zastąpiono ciągiem lib64/.

Aby zapewnić zgodność, dowiązania symboliczne są dostępne w starych ścieżkach. Na przykład /system/lib/libc.so jest dowiązaniem symbolicznym do /apex/com.android.runtime/lib/bionic/libc.so. Dlatego 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 podobne dane. Nie jest to typowe, ale odkryliśmy, że niektóre aplikacje robią to w ramach procesu ochrony przed hakerami. Jeśli tak, ścieżki /apex/… powinny zostać dodane 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 plików binarnych i bibliotek systemowych są mapowane w pamięci tylko do wykonania (bez możliwości odczytu) jako technika wzmacniania zabezpieczeń przed atakami polegającymi na ponownym użyciu kodu. Jeśli aplikacja wykonuje operacje odczytu w segmentach pamięci oznaczonych jako tylko do wykonania – niezależnie od tego, czy jest to spowodowane błędem, luką w zabezpieczeniach czy celową kontrolą pamięci – system wysyła do aplikacji sygnał SIGSEGV.

Możesz sprawdzić, czy to zachowanie spowodowało awarię, analizując powiązany plik tombstone w /data/tombstones/. Awaria związana z wykonywaniem zawiera ten komunikat o przerwaniu:

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żna oznaczyć segmenty tylko do wykonywania jako do odczytu i wykonywania, wywołując funkcję mprotect(). Zdecydowanie zalecamy jednak, aby po zakończeniu testów przywrócić ustawienie „tylko do wykonania”, ponieważ zapewnia ono lepszą ochronę aplikacji i użytkowników.

Bezpieczeństwo

Android 10 wprowadza te zmiany dotyczące bezpieczeństwa.

Protokół TLS 1.3 jest domyślnie włączony

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 naszej implementacji TLS 1.3:

  • Zestawów szyfrów TLS 1.3 nie można dostosowywać. Obsługiwane zestawy szyfrów TLS 1.3 są zawsze włączone, gdy włączony jest protokół TLS 1.3. Każda próba wyłączenia ich przez wywołanie setEnabledCipherSuites() jest ignorowana.
  • Gdy negocjowany jest protokół 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 te obiekty są wywoływane po dodaniu sesji do pamięci podręcznej sesji).
  • W niektórych sytuacjach, gdy instancje SSLEngine zgłaszają błąd SSLHandshakeException w poprzednich wersjach Androida, w Androidzie 10 i nowszych zgłaszają 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, wywołując SSLContext.getInstance("TLSv1.2"). Możesz też włączać i wyłączać wersje protokołu dla poszczególnych połączeń, wywołując metodę setEnabledProtocols() na odpowiednim obiekcie.

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

W Androidzie 10 certyfikaty, które używają algorytmu szyfrowania SHA-1, nie są zaufane w połączeniach TLS. Główne urzędy certyfikacji nie wystawiają takich certyfikatów od 2016 roku i nie są one już uznawane za zaufane w Chrome ani innych głównych przeglądarkach.

Każda próba połączenia się z witryną, która przedstawia certyfikat SHA-1, zakończy się niepowodzeniem.

Zmiany i ulepszenia działania pęku kluczy

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 wydawców i specyfikacji klucza podczas wywoływania KeyChain.choosePrivateKeyAlias(), aby wyświetlić użytkownikom prośbę o wybranie certyfikatu. W szczególności ten prompt nie zawiera opcji, które nie są zgodne ze specyfikacjami serwera.

Jeśli nie ma dostępnych certyfikatów, które użytkownik może wybrać, na przykład gdy żaden certyfikat 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 pojawia.

Ponadto na urządzeniach z Androidem 10 lub nowszym nie jest konieczne ustawienie blokady ekranu, aby importować klucze lub certyfikaty CA do obiektu KeyChain.

Inne zmiany dotyczące TLS i kryptografii

W bibliotekach TLS i kryptograficznych wprowadzono kilka drobnych zmian, które zaczynają obowiązywać w Androidzie 10:

  • Szyfry AES/GCM/NoPadding i ChaCha20/Poly1305/NoPadding zwracają dokładniejsze rozmiary buforów z getOutputSize().
  • Zestaw szyfrów TLS_FALLBACK_SCSV jest pomijany podczas prób połączenia z maksymalnym protokołem TLS 1.2 lub nowszym. Ze względu na ulepszenia w implementacjach serwerów TLS nie zalecamy próby użycia zewnętrznego mechanizmu zastępczego TLS. Zamiast tego zalecamy korzystanie z negocjacji 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.
  • Podczas wybierania klucza podpisywania dla odpowiedzi certyfikatu uwzględniane jest rozszerzenie supported_signature_algorithms w CertificateRequest.
  • Nieprzezroczyste klucze podpisywania, takie jak te z magazynu kluczy Androida, mogą być używane z podpisami RSA-PSS w TLS.

Transmisje Wi-Fi Direct

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

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

Funkcje Wi-Fi Aware

Android 10 dodaje obsługę ułatwiającą tworzenie gniazd TCP/UDP przy użyciu ścieżek danych Wi-Fi 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 przekazywać te informacje poza pasmem, np. za pomocą wiadomości w warstwie 2 Bluetooth lub Wi-Fi Aware, albo wykrywać je w paśmie za pomocą innych protokołów, takich jak mDNS. W Androidzie 10 te informacje mogą być przekazywane 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 w ramach żądania sieciowego Wi-Fi Aware.

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

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 wysyła żądanie sieciowe Wi-Fi Aware, aby uzyskać adres IPv6 i port podany 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 z Androidem 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 nakładek zużywa nadmierną ilość pamięci, co jest szczególnie szkodliwe dla wydajności urządzeń z Androidem o małej ilości pamięci.

Jeśli aplikacja działająca na urządzeniu z Androidem 9 lub starszym w wersji Go otrzyma uprawnienie SYSTEM_ALERT_WINDOW, zachowa je nawet po uaktualnieniu urządzenia do Androida 10. Jednak aplikacje, które nie mają jeszcze tego uprawnienia, nie mogą go otrzymać po uaktualnieniu urządzenia.

Jeśli aplikacja na urządzeniu z Androidem Go wyśle intencję z działaniem ACTION_MANAGE_OVERLAY_PERMISSION, system automatycznie odrzuci żądanie i przekieruje użytkownika do ekranu Ustawienia z informacją, że uprawnienie nie jest dozwolone, ponieważ spowalnia urządzenie. Jeśli aplikacja na urządzeniu z Androidem Go wywoła metodę Settings.canDrawOverlays(), zawsze zwróci ona wartość „false”. Te ograniczenia nie dotyczą aplikacji, które otrzymały uprawnienie SYSTEM_ALERT_WINDOW, zanim urządzenie zostało uaktualnione do Androida 10.

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

Urządzenia z Androidem 10 lub nowszym ostrzegają użytkowników, gdy po raz pierwszy uruchamiają aplikację kierowaną na Androida 5.1 (API na poziomie 22) lub starszego. Jeśli aplikacja wymaga od użytkownika przyznania uprawnień, użytkownik może też dostosować uprawnienia aplikacji przed jej pierwszym uruchomieniem.

Ze względu na wymagania Google Play dotyczące docelowego poziomu interfejsu API 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 podobne wymagania dotyczące docelowego interfejsu API zaczną obowiązywać w 2019 roku. Więcej informacji o tych wymaganiach znajdziesz w artykule Rozszerzanie 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 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 używają GCM, a większość serwerów obsługuje zarówno warianty GCM, jak i CBC tych zestawów szyfrów lub 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 prawidłowo śledzi korzystanie z aplikacji błyskawicznych.

  • Tryb szarości w poszczególnych aplikacjach – Android 10 umożliwia ustawienie trybu szarości w poszczególnych aplikacjach.

  • Stan rozproszenia uwagi dla poszczególnych aplikacji – Android 10 może selektywnie ustawiać aplikacje w „stan rozproszenia uwagi”, w którym ich powiadomienia są wyciszane i nie pojawiają się jako sugerowane aplikacje.

  • Zawieszenie i odtwarzanie – w Androidzie 10 zawieszone aplikacje nie mogą odtwarzać dźwięku.

Zmiany dotyczące połączeń HTTPS

Jeśli aplikacja na Androidzie 10 przekazuje null do setSSLSocketFactory(), występuje błąd IllegalArgumentException. W poprzednich wersjach przekazanie null do setSSLSocketFactory() miało taki sam efekt jak przekazanie bieżącej fabryki 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ą Androida Jetpack. Dodatkowe materiały ułatwiające migrację i programowanie znajdziesz w zaktualizowanym przewodniku po ustawieniach, naszej publicznej przykładowej aplikacji i dokumentacji referencyjnej.

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

Android 10 wprowadza te 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 używają java.util.zip.

Pompka

W poprzednich wersjach niektóre metody w klasie Inflater zgłaszały błąd IllegalStateException, jeśli zostały wywołane po wywołaniu end(). W Androidzie 10 te metody zwracają błąd NullPointerException.

ZipFile

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

ZipOutputStream

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

Zmiany w aparacie

Wiele aplikacji korzystających z aparatu zakłada, że jeśli urządzenie jest w konfiguracji pionowej, to urządzenie fizyczne również jest w orientacji pionowej, jak opisano w sekcji Orientacja aparatu. 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 urządzenia składane. Takie założenie w przypadku tych urządzeń może prowadzić do nieprawidłowego obracania lub skalowania (albo obu tych problemów) obrazu w wizjerze aparatu.

Aplikacje kierowane na interfejs API na poziomie 24 lub wyższym powinny mieć wyraźnie ustawioną wartość android:resizeableActivity i zapewniać niezbędne funkcje do obsługi operacji w trybie wielu okien.

Śledzenie wykorzystania baterii

Począwszy od Androida 10, SystemHealthManager resetuje statystyki użytkowania baterii, gdy urządzenie zostanie odłączone od ładowarki po znacznym naładowaniu. Ogólnie rzecz biorąc, główne zdarzenie ładowania to: urządzenie zostało w pełni naładowane lub urządzenie zostało naładowane od stanu prawie całkowitego rozładowania do stanu prawie całkowitego naładowania.

Przed Androidem 10 statystyki użytkowania baterii były resetowane po odłączeniu urządzenia od ładowarki, niezależnie od tego, jak mało zmienił się poziom baterii.

Wycofanie Android Beam

W Androidzie 10 oficjalnie wycofujemy Android Beam, starszą funkcję do inicjowania udostępniania danych między urządzeniami za pomocą komunikacji Near Field Communication (NFC). Wycofujemy też kilka powiązanych interfejsów API NFC. Android Beam pozostaje opcjonalnie dostępny dla producentów urządzeń, którzy chcą z niego korzystać, ale nie jest już aktywnie rozwijany. Android będzie jednak nadal obsługiwać inne funkcje i interfejsy API NFC, a przypadki użycia, takie jak odczytywanie tagów i płatności, będą nadal działać zgodnie z oczekiwaniami.

Zmiana działania java.math.BigDecimal.stripTrailingZeros()

BigDecimal.stripTrailingZeros() nie zachowuje już zer końcowych jako szczególnego przypadku, jeśli wartość wejściowa wynosi zero.

Zmiany zachowania java.util.regex.Matcher i Pattern

Wynik funkcji split() został zmieniony, aby nie zaczynał się już od pustego ciągu String („”), gdy na początku danych wejściowych występuje dopasowanie o zerowej szerokości. Ma to też wpływ na String.split(). Na przykład "x".split("") zwraca teraz {"x"}, podczas gdy w starszych wersjach Androida zwracało {"", "x"}. "aardvark".split("(?=a)" zwraca teraz {"a", "ardv", "ark"} zamiast {"", "a", "ardv", "ark"}.

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

  • appendReplacement(StringBuffer, String) teraz zgłasza błąd IllegalArgumentException zamiast IndexOutOfBoundsException, jeśli zastąpienie String kończy się pojedynczym ukośnikiem lewym, co jest niedozwolone. Ten sam wyjątek jest teraz zgłaszany, jeśli zastąpienie String kończy się znakiem $. Wcześniej w takiej sytuacji nie był zgłaszany wyjątek.
  • replaceFirst(null) nie wywołuje już reset() w Matcher, jeśli zgłasza błąd NullPointerException. Teraz błąd NullPointerException jest też zgłaszany, gdy nie ma dopasowania. Wcześniej był on zgłaszany tylko wtedy, gdy znaleziono dopasowanie.
  • start(int group), end(int group) i group(int group) teraz zgłaszają bardziej ogólny błąd IndexOutOfBoundsException, jeśli indeks grupy jest poza zakresem. Wcześniej te metody zgłaszały błąd ArrayIndexOutOfBoundsException.

Domyślny kąt dla GradientDrawable to teraz TOP_BOTTOM

Jeśli w Androidzie 10 zdefiniujesz GradientDrawable w pliku XML i nie podasz miary kąta, orientacja gradientu będzie domyślnie ustawiona na TOP_BOTTOM. To zmiana w stosunku do poprzednich wersji Androida, w których domyślną wartością było LEFT_RIGHT.

Aby obejść ten problem, zaktualizuj AAPT2 do najnowszej wersji. Jeśli nie określono kąta, narzędzie ustawia kąt 0 dla starszych aplikacji.

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

Od Androida 7.0 (poziom interfejsu API 24) platforma zawiera poprawkę domyślnego serialVersionUID dla obiektów możliwych do serializacji. Ta poprawka nie miała wpływu na aplikacje kierowane na poziom API 23 lub niższy.

Począwszy od Androida 10, jeśli aplikacja jest kierowana na interfejs API na poziomie 23 lub niższym i korzysta ze starej, nieprawidłowej, domyślnej wartości serialVersionUID, system rejestruje ostrzeżenie i sugeruje 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 serializowana.
  • Zserializowana klasa używa domyślnego serialVersionUID zamiast jawnie ustawionego serialVersionUID.
  • Domyślna wartość serialVersionUID różni się od wartości serialVersionUID, która byłaby używana, gdyby aplikacja była kierowana na interfejs API na poziomie 24 lub wyższym.

To ostrzeżenie jest rejestrowane raz dla każdej klasy, której dotyczy. Komunikat ostrzegawczy zawiera sugerowane rozwiązanie, którym jest wyraźne ustawienie serialVersionUID na wartość domyślną, która zostałaby obliczona, gdyby aplikacja była kierowana na poziom API 24 lub wyższy. 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 poziom 24 lub wyższy i odwrotnie.

Zmiany w java.io.FileChannel.map()

Od Androida 10 funkcja FileChannel.map() nie jest obsługiwana w przypadku plików niestandardowych, takich jak /dev/zero, których rozmiaru nie można zmienić za pomocą truncate(). Poprzednie wersje Androida ignorowały błąd errno zwracany przez truncate(), ale Android 10 zgłasza wyjątek IOException. Jeśli potrzebujesz starego sposobu działania, musisz użyć kodu natywnego.