Zmiany w działaniu: wszystkie aplikacje

Android 10 obejmuje zmiany w działaniu, które mogą wpłynąć na Twoją aplikację. Zmiany wymienione na tej stronie dotyczą Twojej aplikacji uruchomionej w Androidzie 10 bez względu na jej targetSdkVersion. Przetestuj aplikację i w razie potrzeby zmodyfikuj ją, aby prawidłowo obsługiwała te zmiany.

Jeśli parametr targetSdkVersion aplikacji to co najmniej 29, musisz też wprowadzić dodatkowe zmiany. Szczegółowe informacje znajdziesz w zmianach w zachowaniu aplikacji kierowanych na ten typ kierowania na 29.

Uwaga: oprócz zmian wymienionych na tej stronie w Androidzie 10 wprowadziliśmy 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 podobieństwie kontaktów
  • losowa kolejność adresów MAC
  • Metadane z aparatu
  • Model uprawnień

Te zmiany mają wpływ na wszystkie aplikacje i zwiększają prywatność użytkowników. Więcej informacji o tym, jak dostosować się do tych zmian, znajdziesz na stronie Zmiany prywatności.

Ograniczenia interfejsu innego niż SDK

Aby zapewnić stabilność i zgodność aplikacji, platforma zaczęła ograniczać, z których interfejsów innych niż SDK może korzystać aplikacja na Androidzie 9 (poziom API 28). Android 10 zawiera zaktualizowane listy ograniczonych interfejsów spoza SDK opracowane na podstawie współpracy z programistami aplikacji na Androida i najnowszych testów wewnętrznych. Naszym celem jest zapewnienie dostępności publicznych alternatywnych rozwiązań, zanim ograniczymy dostęp do interfejsów spoza SDK.

Jeśli nie będziesz kierować aplikacji na Androida 10 (poziom interfejsu API 29), niektóre z tych zmian mogą Cię nie odczuć od razu. Mimo że obecnie możesz używać niektórych interfejsów spoza pakietu SDK (w zależności od docelowego poziomu interfejsu API aplikacji), korzystanie z dowolnych metod lub pól spoza pakietu SDK niesie ze sobą wysokie ryzyko awarii aplikacji.

Jeśli nie masz pewności, czy Twoja aplikacja używa interfejsów spoza SDK, możesz przetestować ją, aby się tego dowiedzieć. 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 mają odpowiednie przypadki użycia w zakresie interfejsów spoza SDK. Jeśli nie możesz znaleźć alternatywy dla interfejsu innego niż SDK dla funkcji w aplikacji, poproś o nowy publiczny interfejs API.

Więcej informacji znajdziesz w artykule Aktualizacje ograniczeń interfejsu innych niż SDK na Androida 10 oraz Ograniczenia dotyczące interfejsów spoza SDK.

Nawigacja przy użyciu gestów

Począwszy od Androida 10 użytkownicy mogą włączać 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 aplikacja jest kierowana na interfejs API na poziomie 29, czy nie. Jeśli np. użytkownik przesunie palcem od krawędzi ekranu, system zinterpretuje ten gest jako nawigację wstecz, chyba że aplikacja konkretnie zastąpi ten gest w przypadku niektórych części ekranu.

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

Zestaw NDK

W Androidzie 10 wprowadziliśmy opisane poniżej zmiany w pakiecie NDK.

Udostępnione obiekty nie mogą zawierać relokacji tekstu

Android 6.0 (poziom interfejsu API 23) nie może używać przesuwania tekstu w obiektach współdzielonych. Kod musi być wczytywany w takiej postaci, w jakiej jest, i nie można go modyfikować. Ta zmiana wydłuża czas wczytywania i zwiększa bezpieczeństwo aplikacji.

SELinux egzekwuje to ograniczenie w aplikacjach kierowanych na Androida 10 lub nowszego. Jeśli te aplikacje nadal korzystają z obiektów współdzielonych, które zawierają przeniesione tekst, istnieje duże ryzyko ich awarii.

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

Począwszy od Androida 10 kilka ścieżek to dowiązania symboliczne zamiast zwykłych plików. Aplikacje, które używały ścieżek normalnych plików, mogą ulec awarii:

  • /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ą także 64-bitowych wersji pliku, przy czym parametr lib/ został zastąpiony wartością lib64/.

Aby zapewnić zgodność, dowiązania symboliczne są podawane w starych ścieżkach. Na przykład /system/lib/libc.so to dowiązanie symboliczne /apex/com.android.runtime/lib/bionic/libc.so. W związku z tym funkcja dlopen(“/system/lib/libc.so”) nadal działa, ale użytkownicy zauważą różnicę wtedy, gdy usiłują zbadać wczytane biblioteki, odczytując kod /proc/self/maps lub podobny. Nie jest to zwykle możliwe, ale zauważyliśmy, że niektóre aplikacje robią to w ramach procesu zapobiegania atakom hakerów. 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ęć używaną tylko do wykonywania

Począwszy od Androida 10 wykonywalne segmenty plików binarnych i bibliotek systemu są mapowane w pamięć tylko wykonywaną (nieczytelną) w celu ochrony przed atakami typu ponowne użycie kodu. Jeśli aplikacja wykonuje operacje odczytu w segmentach pamięci oznaczonych jako przeznaczone tylko do wykonania – w wyniku kontroli błędów, luk w zabezpieczeniach lub celowej kontroli pamięci – system wysyła do aplikacji sygnał SIGSEGV.

Aby dowiedzieć się, czy to działanie spowodowało awarię, przejrzyj powiązany plik tombstone w /data/tombstones/. Awaria związana tylko 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 wykonywać operacje, takie jak inspekcja pamięci, możesz oznaczyć segmenty tylko do wykonania jako do odczytu i wykonania, wywołując metodę mprotect(). Zdecydowanie zalecamy jednak przywrócenie go do stanu tylko później, ponieważ to ustawienie uprawnień dostępu zapewnia lepszą ochronę aplikacji i użytkowników.

Zabezpieczenia

Android 10 wprowadza te zmiany w zabezpieczeniach.

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

Na urządzeniach z Androidem 10 i nowszym protokół TLS 1.3 jest domyślnie włączony dla wszystkich połączeń TLS. Oto kilka ważnych informacji o implementacji TLS 1.3:

  • Nie można dostosować zestawów szyfrów TLS 1.3. Obsługiwane pakiety mechanizmów szyfrowania TLS 1.3 są zawsze włączone, gdy włączony jest protokół TLS 1.3. Każda próba ich wyłączenia przez wywołanie metody setEnabledCipherSuites() jest ignorowana.
  • Podczas negocjowania protokołu TLS 1.3 obiekty HandshakeCompletedListener są wywoływane przed dodaniem sesji do pamięci podręcznej sesji. W protokole TLS 1.2 i w innych wcześniejszych wersjach obiekty te są nazywane obiektami po dodaniu sesji do pamięci podręcznej sesji.
  • W niektórych sytuacjach, gdy wystąpienia SSLEngine powodują wywołanie SSLHandshakeException w poprzednich wersjach Androida, zamiast tego zwracają błąd SSLProtocolException na Androidzie 10 i nowszych.
  • Tryb 0-RTT nie jest obsługiwany.

W razie potrzeby możesz uzyskać SSLContext z wyłączonym TLS 1.3, wywołując metodę SSLContext.getInstance("TLSv1.2"). Możesz też włączyć lub wyłączyć wersje protokołów dla poszczególnych połączeń, wywołując setEnabledProtocols() przy 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 przypadku połączeń TLS. Główne urzędy certyfikacji nie wystawiały takiego certyfikatu od 2016 r. i nie są już zaufane w Chrome ani w innych popularnych przeglądarkach.

Każda próba nawiązania połączenia nie uda się, jeśli jest ona połączona z witryną prezentującą certyfikat za pomocą SHA-1.

Zmiany w działaniu i ulepszenia działania łańcucha 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 uwzględniają wydawców i parametry specyfikacji klucza podczas wywoływania KeyChain.choosePrivateKeyAlias(), aby wyświetlić użytkownikom prośbę o wybór certyfikatu. W szczególności nie zawiera on opcji niezgodnych ze specyfikacją serwera.

Jeśli nie są dostępne żadne certyfikaty do wyboru przez użytkownika, np. żaden certyfikat nie jest zgodny ze specyfikacją serwera lub na urządzeniu nie są zainstalowane żadne certyfikaty, pytanie o wybór certyfikatu w ogóle się nie pojawia.

Ponadto w Androidzie 10 i nowszych nie trzeba używać blokady ekranu urządzenia do importowania kluczy ani certyfikatów CA do obiektu KeyChain.

Inne zmiany dotyczące protokołu TLS i kryptografii

W Androidzie 10 wprowadzono kilka drobnych zmian w bibliotekach TLS i kryptografii:

  • Mechanizmy AES/GCM/NoPadding i ChaCha20/Poly1305/NoPadding zwraca dokładniejsze rozmiary buforów z getOutputSize().
  • Zestaw szyfrów TLS_FALLBACK_SCSV jest pomijany w przypadku prób połączenia z maksymalnym protokołem TLS w wersji 1.2 lub nowszej. Ze względu na ulepszenia w implementacji serwerów TLS nie zalecamy używania zewnętrznych kreacji zastępczych TLS. Zamiast tego zalecamy wyłącznie negocjowanie wersji TLS.
  • ChaCha20-Poly1305 to alias 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 na potrzeby odpowiedzi na certyfikat respektowane jest rozszerzeniesupported_signature_algorithms w CertificateRequest.
  • Nieprzezroczyste klucze podpisywania, takie jak te z magazynu kluczy Androida, mogą być używane z podpisami RSA-PSS w protokole TLS.

Transmisje przez 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 odbieraniu tych komunikatów podczas rejestracji, ponieważ były one przyklejone, podczas inicjowania użyj odpowiedniej metody get(), aby uzyskać te informacje.

Funkcje Wi-Fi Aware

Android 10 dodaje obsługę, która ułatwia 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. Do tej pory musiały być przekazywane poza pasmem, na przykład za pomocą BT lub Wi-Fi Aware w warstwie 2, albo wykrywane w paśmie 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 pobierz port do użycia.
  • Podaj informacje o porcie w żądaniu sieci 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 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 Go

Aplikacje działające na urządzeniach z Androidem 10 (wersja Go) nie mogą otrzymać uprawnień SYSTEM_ALERT_WINDOW. Dzieje się tak, ponieważ nakładki rysowania wykorzystują 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 uruchomiona na urządzeniu w wersji Go z Androidem 9 lub starszym otrzyma uprawnienie SYSTEM_ALERT_WINDOW, aplikacja zachowa to uprawnienie nawet po przejściu na Androida 10. Jednak aplikacje, które nie mają jeszcze takiego uprawnienia, nie będą mogły 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 takie żądanie i wyświetla ekran Ustawienia z komunikatem, że uprawnienie jest niedozwolone, ponieważ spowalnia działanie urządzenia. Jeśli aplikacja na urządzeniu Go wywołuje metodę Settings.canDrawOverlays(), ta metoda zawsze zwraca wartość false (fałsz). Te ograniczenia nie dotyczą aplikacji, które otrzymały uprawnienie SYSTEM_ALERT_WINDOW przed aktualizacją urządzenia do Androida 10.

Ostrzeżenia dla aplikacji kierowanych na starsze wersje Androida

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

Ze względu na wymagania Google Play dotyczące docelowego 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 w 2019 r. zaczną obowiązywać podobne wymagania dotyczące docelowych interfejsów API. Więcej informacji o tych wymaganiach znajdziesz w artykule Rozszerzanie wymagań dotyczących docelowego poziomu interfejsu API w 2019 roku.

Zestawy szyfrów SHA-2 CBC zostały usunięte

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 korzystające z GCM, a większość serwerów obsługuje zarówno wersje GCM, jak i CBC tych pakietów szyfrów, albo żaden z nich.

Transmisja danych w aplikacjach

W Androidzie 10 wprowadziliśmy te zmiany w działaniu związane z korzystaniem z aplikacji:

  • Statystyki użytkowania Dodatkowo Android 10 prawidłowo śledzi użycie aplikacji błyskawicznych.

  • Tryb szarości według aplikacji

  • Stan rozproszenia uwagi przez aplikację - aplikacja może wyświetlić się

  • Zawieszenie i odtwarzanie -

Zmiany połączenia HTTPS

Jeśli aplikacja na Androida 10 przekazuje kod null do setSSLSocketFactory(), występuje IllegalArgumentException. W poprzednich wersjach przekazywanie null do setSSLSocketFactory() dawało taki sam efekt jak przekazywanie bieżącej domyślnej wartości fabrycznej.

Biblioteka android.preference została wycofana

W Androidzie 10 biblioteka android.preference została wycofana. Deweloperzy powinni korzystać z biblioteki ustawień AndroidX, która jest częścią pakietu AndroidJetpack. Dodatkowe zasoby ułatwiające migrację i programowanie znajdziesz w zaktualizowanym przewodniku po ustawieniach, a także w publicznej przykładowej aplikacji i dokumentacji referencyjnej.

Zmiany w bibliotece narzędzi plików ZIP

W Androidzie 10 wprowadzono opisane poniżej zmiany w klasach w pakiecie java.util.zip, które obsługują pliki ZIP. Dzięki tym zmianom działanie biblioteki będzie bardziej spójne na Androidzie i innych platformach korzystających z java.util.zip.

Dmuchany

W poprzednich wersjach niektóre metody w klasie Inflater zwracały element IllegalStateException, jeśli został on wywołany po wywołaniu end(). W Androidzie 10 te metody powodują zamiast tego NullPointerException.

Plik ZIP

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

ZipExitStream

W Androidzie 10 i nowszych metoda finish() w ZipOutputStream nie zgłasza ZipException, gdy 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 pionie, to jego fizyczne urządzenie również jest w orientacji pionowej (zgodnie z opisem w sekcji Orientacja aparatu). W przeszłości było to bezpieczne założenie, ale zmieniło się to w miarę rozwoju dostępnych formatów, np. urządzeń składanych. W przypadku takich urządzeń założenie może skutkować niewłaściwym obróceniem lub przeskalowaniem wizjera aparatu (bądź jednym i drugim).

Aplikacje kierowane na interfejs API na poziomie 24 lub wyższym powinny bezpośrednio ustawiać właściwość android:resizeableActivity i zapewniać niezbędną funkcjonalność do obsługi wielu okien.

Śledzenie wykorzystania baterii

Od Androida 10 SystemHealthManager resetuje statystyki wykorzystania baterii za każdym razem, gdy urządzenie jest odłączone od zasilania po poważnym obciążeniu. Ogólnie rzecz biorąc, częstsze zdarzenia związane z ładowaniem to: pełne naładowanie urządzenia lub to, że jest ono w większości rozładowane.

Przed Androidem 10 statystyki użytkowania baterii były resetowane po każdym odłączeniu urządzenia, niezależnie od tego, jak bardzo zmieniła się poziom naładowania baterii.

Wycofanie funkcji Android Beam

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

Zmiana zachowania java.math.BigDecimal.stripTrailingZeros()

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

Zmiany w zachowaniu poleceń java.util.regex.Matcher i wzorca

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

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

  • appendReplacement(StringBuffer, String) zwraca teraz IllegalArgumentException zamiast IndexOutOfBoundsException, jeśli miejsce docelowe String kończy się pojedynczym ukośnikiem lewym, co jest niezgodne z prawem. Ten sam wyjątek jest teraz zwracany, jeśli zastępujący String kończy się wartością $. Wcześniej w tej sytuacji nie było żadnego wyjątku.
  • replaceFirst(null) nie wywołuje już funkcji reset() na urządzeniu Matcher, jeśli generuje kod NullPointerException. Jeśli nie ma dopasowania, kod NullPointerException jest teraz wywoływany. Wcześniej był on wysyłany tylko wtedy, gdy znaleziono dopasowanie.
  • start(int group), end(int group) i group(int group) zgłaszają teraz bardziej ogólną wartość IndexOutOfBoundsException, jeśli indeks grupy jest poza zakresem. Wcześniej te metody powodowały zwracanie wyników ArrayIndexOutOfBoundsException.

Domyślny kąt w funkcji GradientDrawable to teraz TOP_BOTTOM

Na Androidzie 10, jeśli zdefiniujesz obiekt GradientDrawable w pliku XML, ale nie podasz pomiaru kąta, orientacja gradientu zostanie ustawiona na TOP_BOTTOM. To zmiana w porównaniu z poprzednimi wersjami Androida, których wartością domyślną była LEFT_RIGHT.

Aby obejść ten problem, po aktualizacji do najnowszej wersji AAPT2 narzędzie ustawi pomiar kąta na 0 dla starszych aplikacji, jeśli nie określono pomiaru kąta.

Logowanie obiektów zserializowanych z użyciem domyślnego identyfikatora SUID

Począwszy od Androida 7.0 (poziom interfejsu API 24) platforma wprowadziła poprawkę w domyślnej wartości serialVersionUID dotyczącej obiektów możliwych do serializowania. Ta poprawka nie miała 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 starej, nieprawidłowej, domyślnej wersji serialVersionUID, system zarejestruje ostrzeżenie i zaproponuje poprawkę w kodzie.

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.
  • Zserializowana klasa używa domyślnej wartości serialVersionUID, zamiast jednoznacznie ustawiać serialVersionUID.
  • Domyślna wartość serialVersionUID różni się od wartości serialVersionUID, jeśli jest kierowana na interfejs API na poziomie 24 lub wyższym.

To ostrzeżenie jest rejestrowane raz dla każdej klasy, której dotyczy problem. Komunikat ostrzegawczy zawiera sugerowaną poprawkę, czyli jawne ustawienie parametru serialVersionUID na wartość domyślną, która zostałaby obliczona w przypadku interfejsu API kierowanego na aplikację na poziomie 24 lub wyższym. Dzięki tej poprawce możesz zapewnić, że jeśli obiekt z tej klasy zostanie zserializowany w aplikacji kierowanej na interfejs API na poziomie 23 lub niższym, będzie on poprawnie odczytywany przez aplikacje kierowane na wersję 24 lub wyższą.

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 nie dopuszczały błędów zwracanych przez funkcję truncate(), ale Android 10 zgłasza wyjątek IOWyjątek. Jeśli potrzebujesz starego sposobu działania, musisz użyć kodu natywnego.