Thay đổi về hành vi: tất cả ứng dụng

Android 10 có các thay đổi về hành vi có thể ảnh hưởng đến ứng dụng của bạn. Những thay đổi được liệt kê trên trang này áp dụng cho ứng dụng của bạn khi chạy trên Android 10, bất kể targetSdkVersion của ứng dụng là gì. Bạn nên kiểm thử ứng dụng rồi sửa đổi để hỗ trợ những thay đổi này cho phù hợp.

Nếu targetSdkVersion của ứng dụng là 29 trở lên, bạn cũng cần hỗ trợ thêm các thay đổi khác. Hãy nhớ đọc các thay đổi về hành vi đối với ứng dụng nhắm đến API cấp 29 để biết thông tin chi tiết.

Lưu ý: Ngoài những thay đổi được liệt kê trên trang này, Android 10 còn giới thiệu một số lượng lớn các thay đổi và hạn chế dựa trên quyền riêng tư, bao gồm cả những thay đổi sau:

  • Quyền truy cập vị trí thiết bị khi ở nền sau
  • Hoạt động ở chế độ nền bắt đầu
  • Thông tin về mức độ thân thiết với danh bạ
  • Ngẫu nhiên hoá địa chỉ MAC
  • Siêu dữ liệu của máy ảnh
  • Mô hình quản lý quyền

Những thay đổi này ảnh hưởng đến tất cả ứng dụng và tăng cường quyền riêng tư của người dùng. Để tìm hiểu thêm về cách hỗ trợ những thay đổi này, hãy xem trang Thay đổi về quyền riêng tư.

Các hạn chế đối với giao diện không phải SDK

Để giúp đảm bảo tính ổn định và khả năng tương thích của ứng dụng, nền tảng này bắt đầu hạn chế các giao diện không phải SDK mà ứng dụng của bạn có thể sử dụng trong Android 9 (API cấp 28). Android 10 cung cấp danh sách mới cập nhật về các giao diện không phải SDK bị hạn chế dựa trên khả năng cộng tác với nhà phát triển Android và quy trình kiểm thử nội bộ mới nhất. Mục tiêu của chúng tôi là đảm bảo cung cấp các phương án thay thế công khai trước khi hạn chế giao diện không phải SDK.

Nếu bạn không nhắm đến Android 10 (cấp độ API 29), thì một số thay đổi này có thể sẽ không ảnh hưởng ngay. Tuy nhiên, mặc dù hiện tại bạn có thể sử dụng một số giao diện không phải SDK (tuỳ thuộc vào cấp độ API mục tiêu của ứng dụng), nhưng việc sử dụng phương thức hoặc trường không phải SDK luôn có nguy cơ cao làm hỏng ứng dụng.

Nếu không chắc ứng dụng của mình có sử dụng giao diện không phải SDK hay không, bạn có thể kiểm tra ứng dụng để tìm hiểu. Nếu ứng dụng của bạn dựa vào giao diện không phải SDK, thì bạn nên bắt đầu lập kế hoạch di chuyển sang SDK làm giải pháp thay thế. Tuy nhiên, chúng tôi hiểu rằng vẫn có một số trường hợp sử dụng hợp lệ cho việc ứng dụng sử dụng giao diện không phải SDK. Nếu không tìm được giải pháp thay thế cho việc sử dụng giao diện không phải SDK cho một tính năng trong ứng dụng, thì bạn nên yêu cầu một API công khai mới.

Để tìm hiểu thêm, hãy xem bài viết Nội dung cập nhật đối với các hạn chế về giao diện không phải SDK trong Android 10 và xem bài viết Các hạn chế đối với giao diện không phải SDK.

Điều hướng bằng cử chỉ

Kể từ Android 10, người dùng có thể bật tính năng điều hướng bằng cử chỉ trên thiết bị. Nếu người dùng bật tính năng điều hướng bằng cử chỉ, thì tính năng này sẽ ảnh hưởng đến tất cả ứng dụng trên thiết bị, bất kể ứng dụng có nhắm đến API cấp 29 hay không. Ví dụ: nếu người dùng vuốt từ cạnh màn hình vào , hệ thống sẽ diễn giải cử chỉ đó là thao tác điều hướng Quay lại , trừ phi một ứng dụng ghi đè cụ thể cử chỉ đó cho các phần của màn hình.

Để giúp ứng dụng của bạn tương thích với tính năng điều hướng bằng cử chỉ, bạn nên mở rộng nội dung ứng dụng từ cạnh này sang cạnh kia và xử lý các cử chỉ xung đột một cách thích hợp. Để biết thông tin, hãy xem tài liệu về Điều hướng bằng cử chỉ.

NDK

Android 10 có các thay đổi sau đây đối với NDK.

Các đối tượng dùng chung không thể chứa các hình thức chuyển vị trí văn bản

Android 6.0 (cấp độ API 23) không cho phép sử dụng các hình thức chuyển vị trí văn bản trong các đối tượng dùng chung. Mã phải được tải nguyên trạng và không được sửa đổi. Thay đổi này giúp cải thiện thời gian tải ứng dụng và tính bảo mật.

SELinux thực thi hạn chế này đối với các ứng dụng nhắm đến Android 10 trở lên. Nếu các ứng dụng này tiếp tục sử dụng các đối tượng dùng chung có chứa các hình thức chuyển vị trí văn bản, thì chúng có nguy cơ cao bị hỏng.

Thay đổi đối với thư viện Bionic và đường dẫn trình liên kết động

Kể từ Android 10, một số đường dẫn là đường liên kết tượng trưng thay vì tệp thông thường. Các ứng dụng dựa vào các đường dẫn là tệp thông thường có thể bị hỏng:

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

Những thay đổi này cũng áp dụng cho các biến thể 64 bit của tệp, trong đó lib/ được thay thế bằng lib64/.

Để đảm bảo khả năng tương thích, các symlink được cung cấp ở các đường dẫn cũ. Ví dụ: /system/lib/libc.so là một symlink đến /apex/com.android.runtime/lib/bionic/libc.so. Vì vậy, dlopen(“/system/lib/libc.so”) tiếp tục hoạt động, nhưng các ứng dụng sẽ thấy sự khác biệt khi thực sự cố gắng kiểm tra các thư viện đã tải bằng cách đọc /proc/self/maps hoặc tương tự. Đây không phải là điều thường thấy nhưng chúng tôi nhận thấy một số ứng dụng làm như vậy trong quá trình chống xâm nhập. Nếu vậy, các đường dẫn /apex/… sẽ được thêm làm đường dẫn hợp lệ cho các tệp Bionic.

Các tệp nhị phân/thư viện hệ thống được ánh xạ để chỉ thực thi bộ nhớ

Kể từ Android 10, các phân đoạn có thể thực thi của các tệp nhị phân và thư viện hệ thống được ánh xạ vào bộ nhớ chỉ thực thi (không thể đọc) như một kỹ thuật tăng cường chống lại các cuộc tấn công sử dụng lại mã. Nếu ứng dụng của bạn thực hiện các thao tác đọc vào các phân đoạn bộ nhớ được đánh dấu là chỉ thực thi – cho dù là do lỗi, lỗ hổng hay kiểm tra bộ nhớ có chủ ý – thì hệ thống sẽ gửi tín hiệu SIGSEGV đến ứng dụng của bạn.

Bạn có thể xác định xem hành vi này có gây ra sự cố hay không bằng cách kiểm tra tệp bia mộ liên quan trong /data/tombstones/. Sự cố liên quan đến chỉ thực thi chứa thông báo huỷ bỏ sau đây:

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

Để giải quyết vấn đề này nhằm thực hiện các thao tác như kiểm tra bộ nhớ, bạn có thể đánh dấu các phân đoạn chỉ thực thi là đọc+thực thi bằng cách gọi mprotect(). Tuy nhiên, chúng tôi đặc biệt khuyên bạn nên đặt lại thành chỉ thực thi sau đó, vì chế độ cài đặt quyền truy cập này giúp bảo vệ tốt hơn cho ứng dụng và người dùng của bạn.

Bảo mật

Android 10 có các thay đổi sau đây về bảo mật.

TLS 1.3 được bật theo mặc định

Trên Android 10 trở lên, TLS 1.3 được bật theo mặc định cho mọi kết nối TLS. Dưới đây là một số thông tin quan trọng về hoạt động triển khai TLS 1.3 của chúng tôi:

  • Bộ thuật toán mật mã TLS 1.3 không tuỳ chỉnh được. Bộ thuật toán mật mã TLS 1.3 được hỗ trợ luôn bật khi TLS 1.3 được bật. Mọi nỗ lực tắt chúng bằng cách gọi setEnabledCipherSuites() đều bị bỏ qua.
  • Khi thương lượng TLS 1.3, HandshakeCompletedListener các đối tượng sẽ được gọi trước khi các phiên được thêm vào bộ nhớ đệm của phiên. (Trong TLS 1.2 và các phiên bản khác trước đó, các đối tượng này được gọi sau khi phiên được thêm vào bộ nhớ đệm của phiên.)
  • Trong một số trường hợp mà các thực thể SSLEngine gửi một SSLHandshakeException trên các phiên bản Android trước đó, các thực thể này sẽ gửi một SSLProtocolException thay vì trên Android 10 trở lên.
  • Không hỗ trợ chế độ 0-RTT.

Nếu muốn, bạn có thể lấy một SSLContext đã vô hiệu hoá TLS 1.3 bằng cách gọi SSLContext.getInstance("TLSv1.2"). Bạn cũng có thể bật hoặc tắt các phiên bản giao thức trên cơ sở mỗi kết nối bằng cách gọi setEnabledProtocols() trên một đối tượng thích hợp.

Các chứng chỉ được ký bằng SHA-1 không đáng tin cậy trong TLS

Trên Android 10, các chứng chỉ sử dụng thuật toán hàm băm SHA-1 sẽ không được tin cậy trong các kết nối TLS. Các CA gốc không phát hành những chứng chỉ như vậy kể từ năm 2016 và chúng không còn đáng tin cậy trong Chrome hoặc các trình duyệt lớn khác.

Mọi nỗ lực kết nối đều không thành công nếu kết nối đó là đến một trang web trình bày chứng chỉ bằng SHA-1.

Các thay đổi và điểm cải thiện trong hành vi của KeyChain

Một số trình duyệt, chẳng hạn như Google Chrome, cho phép người dùng chọn chứng chỉ khi máy chủ TLS gửi một thông báo yêu cầu chứng chỉ trong quá trình bắt tay TLS. Kể từ Android 10, KeyChain các đối tượng sẽ tôn trọng tổ chức phát hành và các thông số kỹ thuật chính khi gọi KeyChain.choosePrivateKeyAlias() để cho người dùng thấy lời nhắc lựa chọn chứng chỉ. Cụ thể, lời nhắc này không chứa các lựa chọn không tuân thủ thông số kỹ thuật của máy chủ.

Nếu không có chứng chỉ nào mà người dùng có thể chọn, chẳng hạn như khi không có chứng chỉ nào khớp với thông số kỹ thuật của máy chủ hoặc thiết bị không cài đặt bất kỳ chứng chỉ nào, thì lời nhắc chọn chứng chỉ sẽ không xuất hiện.

Ngoài ra, trên Android 10 trở lên, bạn không nhất thiết phải có phương thức khoá màn hình thiết bị để nhập các khoá hoặc chứng chỉ CA vào đối tượng KeyChain.

Những thay đổi khác về TLS và mật mã học

Dưới đây là một số thay đổi nhỏ trong thư viện TLS và mật mã học có hiệu lực trên Android 10:

  • Các thuật toán mật mã AES/GCM/NoPadding và ChaCha20/Poly1305/NoPadding sẽ trả về dung lượng bộ nhớ đệm chính xác hơn từ getOutputSize().
  • Bộ thuật toán mật mã TLS_FALLBACK_SCSV bị loại bỏ khỏi các nỗ lực kết nối bằng một giao thức max TLS 1.2 trở lên. Do hoạt động triển khai máy chủ TLS đã được cải thiện, bạn không nên thử phương thức dự phòng TLS bên ngoài. Thay vào đó, bạn nên dựa vào quá trình thương lượng phiên bản TLS.
  • ChaCha20-Poly1305 là bí danh của ChaCha20/Poly1305/NoPadding.
  • Tên máy chủ có dấu chấm theo sau không được xem là tên máy chủ SNI hợp lệ.
  • Phần mở rộng supported_signature_algorithms trong CertificateRequest được tuân thủ khi chọn khoá ký cho các phản hồi chứng chỉ.
  • Bạn có thể dùng các khoá ký mờ (chẳng hạn như các khoá trong Kho khoá Android) với chữ ký RSA-PSS trong TLS.

Thông báo truyền tin Wi-Fi Direct

Trên Android 10, các thông báo truyền tin sau đây liên quan đến Wi-Fi Direct không phải là thông báo truyền tin cố định:

Nếu ứng dụng của bạn dựa vào việc nhận các thông báo truyền tin này khi đăng ký vì chúng là thông báo truyền tin cố định, hãy sử dụng phương thức get() thích hợp khi khởi chạy để lấy thông tin.

Các tính năng của Wi-Fi Aware

Android 10 bổ sung tính năng hỗ trợ để dễ dàng tạo Socket TCP/UDP bằng cách sử dụng đường dẫn dữ liệu Wi-Fi Aware. Để tạo một socket TCP/UDP kết nối với ServerSocket, thiết bị máy khách cần biết địa chỉ IPv6 và cổng của máy chủ. Trước đây, thông tin này cần được truyền đạt ngoài băng tần, chẳng hạn như bằng cách sử dụng tin nhắn BT hoặc Wi-Fi Aware lớp 2, hoặc được phát hiện trong băng tần bằng các giao thức khác, chẳng hạn như mDNS. Với Android 10, thông tin có thể được truyền đạt trong quá trình thiết lập mạng.

Máy chủ có thể thực hiện một trong những thao tác sau:

  • Khởi chạy ServerSocket và đặt hoặc lấy cổng sẽ sử dụng.
  • Chỉ định thông tin cổng trong yêu cầu mạng Wi-Fi Aware.

Mẫu mã sau đây cho thấy cách chỉ định thông tin cổng trong yêu cầu mạng:

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();

Sau đó, máy khách thực hiện yêu cầu mạng Wi-Fi Aware để lấy IPv6 và cổng do máy chủ cung cấp:

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 trên thiết bị Go

Các ứng dụng chạy trên thiết bị Android 10 (phiên bản Go) không thể nhận SYSTEM_ALERT_WINDOW quyền. Lý do là vì việc vẽ các cửa sổ lớp phủ sử dụng quá nhiều bộ nhớ, điều này đặc biệt gây hại cho hiệu suất của các thiết bị Android có bộ nhớ thấp.

Nếu một ứng dụng chạy trên thiết bị phiên bản Go chạy Android 9 trở xuống nhận được quyền SYSTEM_ALERT_WINDOW, thì ứng dụng đó sẽ giữ lại quyền này ngay cả khi thiết bị được nâng cấp lên Android 10. Tuy nhiên, các ứng dụng chưa có quyền đó sẽ không được cấp quyền sau khi thiết bị được nâng cấp.

Nếu một ứng dụng trên thiết bị Go gửi ý định có hành động ACTION_MANAGE_OVERLAY_PERMISSION, thì hệ thống sẽ tự động từ chối yêu cầu và đưa người dùng đến màn hình Cài đặt cho biết rằng quyền này không được phép vì làm chậm thiết bị. Nếu một ứng dụng trên thiết bị Go gọi Settings.canDrawOverlays(), thì phương thức này luôn trả về giá trị false. Xin nhắc lại rằng những hạn chế này không áp dụng cho các ứng dụng đã nhận được quyền SYSTEM_ALERT_WINDOW trước khi thiết bị được nâng cấp lên Android 10.

Cảnh báo cho các ứng dụng nhắm đến các phiên bản Android cũ

Các thiết bị chạy Android 10 trở lên sẽ cảnh báo người dùng lần đầu tiên họ chạy bất kỳ ứng dụng nào nhắm đến Android 5.1 (cấp độ API 22) trở xuống. Nếu ứng dụng yêu cầu người dùng cấp quyền, thì người dùng cũng có cơ hội điều chỉnh quyền của ứng dụng trước khi ứng dụng được phép chạy lần đầu tiên.

Do các yêu cầu của Google Play về API mục tiêu yêu cầu, người dùng chỉ thấy những cảnh báo này khi chạy một ứng dụng chưa được cập nhật gần đây. Đối với các ứng dụng được phân phối thông qua các cửa hàng khác, các yêu cầu tương tự về API mục tiêu sẽ có hiệu lực trong năm 2019. Để biết thêm thông tin về các yêu cầu này, hãy xem bài viết Mở rộng các yêu cầu về cấp độ API mục tiêu trong năm 2019.

Đã xoá bộ thuật toán mật mã SHA-2 CBC

Các bộ thuật toán mật mã SHA-2 CBC sau đây đã bị xoá khỏi nền tảng:

  • 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

Các bộ thuật toán mật mã này kém an toàn hơn các bộ thuật toán mật mã tương tự sử dụng GCM và hầu hết các máy chủ đều hỗ trợ cả biến thể GCM và CBC của các bộ thuật toán mật mã này hoặc không hỗ trợ cả hai.

Sử dụng ứng dụng

Android 10 giới thiệu các thay đổi sau đây về hành vi liên quan đến việc sử dụng ứng dụng:

  • Cải thiện việc sử dụng ứng dụng UsageStats - Android 10 theo dõi chính xác việc sử dụng ứng dụng bằng UsageStats khi các ứng dụng được sử dụng ở chế độ chia đôi màn hình hoặc hình trong hình. Ngoài ra, Android 10 theo dõi chính xác việc sử dụng ứng dụng tức thì.

  • Thang màu xám cho mỗi ứng dụng - Android 10 có thể đặt chế độ hiển thị thang màu xám trên cơ sở mỗi ứng dụng.

  • Trạng thái gây xao nhãng cho mỗi ứng dụng - Android 10 có thể chọn đặt các ứng dụng ở "trạng thái gây xao nhãng" trong đó thông báo của chúng bị chặn và chúng không xuất hiện dưới dạng ứng dụng được đề xuất.

  • Tạm ngưng và phát - Trong Android 10, các ứng dụng bị tạm ngưng không thể phát âm thanh.

Các thay đổi về kết nối HTTPS

Nếu một ứng dụng chạy Android 10 truyền null vào setSSLSocketFactory(), thì sẽ xảy ra IllegalArgumentException. Trong các phiên bản trước, việc truyền null vào setSSLSocketFactory() có cùng kết quả như khi truyền vào factory mặc định hiện tại.

Thư viện android.preference không được dùng nữa

Thư viện android.preference không được dùng nữa kể từ Android 10. Thay vào đó, nhà phát triển nên sử dụng thư viện tuỳ chọn AndroidX, một phần của Android Jetpack. Để biết thêm tài nguyên hỗ trợ quá trình di chuyển và phát triển, hãy xem Hướng dẫn cài đặt đã cập nhật cùng với ứng dụng mẫu công khai và tài liệu tham khảo của chúng tôi.

Thay đổi đối với thư viện tiện ích tệp ZIP

Android 10 giới thiệu các thay đổi sau đây đối với các lớp trong gói java.util.zip, xử lý các tệp ZIP. Những thay đổi này giúp hành vi của thư viện nhất quán hơn giữa Android và các nền tảng khác sử dụng java.util.zip.

Inflater

Trong các phiên bản trước, một số phương thức trong lớp Inflater đã gửi một IllegalStateException nếu chúng được gọi sau khi gọi end(). Trong Android 10, các phương thức này sẽ gửi một NullPointerException thay vì.

ZipFile

Trong Android 10 trở lên, hàm khởi tạo cho ZipFile nhận các đối số thuộc loại File, intCharset sẽ không gửi một ZipException nếu tệp ZIP được cung cấp không chứa tệp nào.

ZipOutputStream

Trong Android 10 trở lên, phương thức finish() trong ZipOutputStream sẽ không gửi một ZipException nếu phương thức này cố gắng ghi luồng đầu ra cho một tệp ZIP không chứa tệp nào.

Thay đổi đối với máy ảnh

Nhiều ứng dụng sử dụng máy ảnh giả định rằng nếu thiết bị ở cấu hình dọc, thì thiết bị thực cũng ở hướng dọc, như mô tả trong phần Hướng máy ảnh. Đây là một giả định an toàn trong quá khứ, nhưng điều đó đã thay đổi khi các hệ số hình thức có sẵn được mở rộng, chẳng hạn như thiết bị có thể gập lại. Giả định đó trên các thiết bị này có thể dẫn đến việc hiển thị kính ngắm của máy ảnh bị xoay hoặc thu phóng không chính xác (hoặc cả hai).

Các ứng dụng nhắm đến cấp độ API mục tiêu 24 trở lên phải đặt rõ ràng android:resizeableActivity và cung cấp chức năng cần thiết để xử lý hoạt động nhiều cửa sổ.

Theo dõi mức sử dụng pin

Kể từ Android 10, SystemHealthManager sẽ đặt lại số liệu thống kê về mức sử dụng pin bất cứ khi nào thiết bị bị rút phích cắm sau một sự kiện sạc lớn. Nói chung, sự kiện sạc lớn là: Thiết bị đã được sạc đầy hoặc thiết bị đã chuyển từ gần hết pin sang gần đầy pin.

Trước Android 10, số liệu thống kê về mức sử dụng pin sẽ đặt lại bất cứ khi nào thiết bị bị rút phích cắm, bất kể mức pin thay đổi ít như thế nào.

Ngừng sử dụng Truyền tia Android

Trong Android 10, chúng tôi chính thức ngừng sử dụng Truyền tia Android, một tính năng cũ để bắt đầu chia sẻ dữ liệu trên các thiết bị thông qua Giao tiếp phạm vi gần (NFC). Chúng tôi cũng ngừng sử dụng một số API NFC liên quan. Truyền tia Android vẫn có thể được các đối tác nhà sản xuất thiết bị sử dụng nếu họ muốn, nhưng tính năng này không còn được phát triển tích cực nữa. Tuy nhiên, Android sẽ tiếp tục hỗ trợ các tính năng và API NFC khác và các trường hợp sử dụng như đọc từ thẻ và thanh toán sẽ tiếp tục hoạt động như mong đợi.

Thay đổi về hành vi của java.math.BigDecimal.stripTrailingZeros()

BigDecimal.stripTrailingZeros() không còn giữ lại các số 0 ở cuối dưới dạng trường hợp đặc biệt nếu giá trị đầu vào là 0.

Thay đổi về hành vi của java.util.regex.Matcher và Pattern

Kết quả của split() đã thay đổi để không còn bắt đầu bằng String ("") trống khi có kết quả khớp có độ rộng bằng 0 ở đầu đầu vào. Điều này cũng ảnh hưởng đến String.split(). Ví dụ: "x".split("") hiện trả về {"x"} trong khi trước đây trả về {"", "x"} trên các phiên bản Android cũ. "aardvark".split("(?=a)" hiện trả về {"a", "ardv", "ark"} thay vì {"", "a", "ardv", "ark"}.

Hành vi ngoại lệ đối với các đối số không hợp lệ cũng đã được cải thiện:

  • appendReplacement(StringBuffer, String) hiện gửi một IllegalArgumentException thay vì IndexOutOfBoundsException nếu thay thế String kết thúc bằng một dấu gạch chéo ngược đơn, điều này là không hợp lệ. Ngoại lệ tương tự hiện được gửi nếu String thay thế kết thúc bằng $. Trước đây, không có ngoại lệ nào được gửi trong trường hợp này.
  • replaceFirst(null) không còn gọi reset() trên Matcher nếu phương thức này gửi một NullPointerException. NullPointerException hiện cũng được gửi khi không có kết quả khớp. Trước đây, phương thức này chỉ được gửi khi có kết quả khớp.
  • start(int group), end(int group)group(int group) hiện gửi một IndexOutOfBoundsException chung hơn nếu chỉ mục nhóm nằm ngoài phạm vi. Trước đây, các phương thức này đã gửi ArrayIndexOutOfBoundsException.

Góc mặc định cho GradientDrawable hiện là TOP_BOTTOM

Trong Android 10, nếu bạn xác định GradientDrawable trong XML và không cung cấp số đo góc, thì hướng gradient sẽ mặc định là TOP_BOTTOM. Đây là thay đổi so với các phiên bản Android trước, trong đó giá trị mặc định là LEFT_RIGHT.

Để giải quyết vấn đề này, nếu bạn cập nhật lên phiên bản AAPT2 mới nhất, công cụ này sẽ đặt số đo góc là 0 cho các ứng dụng cũ nếu không chỉ định số đo góc.

Ghi nhật ký cho các đối tượng được tuần tự hoá bằng SUID mặc định

Kể từ Android 7.0 (cấp độ API 24), nền tảng này đã khắc phục lỗi đối với serialVersionUID mặc định cho các đối tượng có thể tuần tự hoá. Bản sửa lỗi này không ảnh hưởng đến các ứng dụng nhắm đến API cấp 23 trở xuống.

Kể từ Android 10, nếu một ứng dụng nhắm đến API cấp 23 trở xuống và dựa vào serialVersionUID mặc định cũ, không chính xác, thì hệ thống sẽ ghi nhật ký cảnh báo và đề xuất bản sửa lỗi mã.

Cụ thể, hệ thống sẽ ghi nhật ký cảnh báo nếu tất cả điều kiện sau đây đều đúng:

  • Ứng dụng nhắm đến API cấp 23 trở xuống.
  • Một lớp được tuần tự hoá.
  • Lớp được tuần tự hoá sử dụng serialVersionUID mặc định, thay vì đặt rõ ràng serialVersionUID.
  • serialVersionUID mặc định khác với serialVersionUID nếu ứng dụng nhắm đến API cấp 24 trở lên.

Cảnh báo này được ghi nhật ký một lần cho mỗi lớp bị ảnh hưởng. Thông báo cảnh báo bao gồm bản sửa lỗi được đề xuất, đó là đặt rõ ràng serialVersionUID thành giá trị mặc định sẽ được tính toán nếu ứng dụng nhắm đến API cấp 24 trở lên. Bằng cách sử dụng bản sửa lỗi đó, bạn có thể đảm bảo rằng nếu một đối tượng từ lớp đó được chuyển đổi tuần tự trên một ứng dụng nhắm đến cấp độ API mục tiêu 23 trở xuống, thì đối tượng đó sẽ được các ứng dụng nhắm đến cấp độ API mục tiêu 24 trở lên đọc chính xác và ngược lại.

Thay đổi đối với java.io.FileChannel.map()

Kể từ Android 10, FileChannel.map() không được hỗ trợ cho các tệp không chuẩn, chẳng hạn như /dev/zero, có kích thước không thể thay đổi bằng truncate(). Các phiên bản Android trước đã nuốt errno do truncate() trả về, nhưng Android 10 sẽ gửi một IOException. Nếu bạn cần hành vi cũ, bạn phải sử dụng mã gốc.