Các thay đổi về hành vi của Android 8.0

Cùng với các tính năng và khả năng mới, Android 8.0 (API cấp 26) bao gồm nhiều thay đổi về hành vi của hệ thống và API. Tài liệu này nêu bật một số thay đổi quan trọng mà bạn nên hiểu rõ và lưu tâm đến trong ứng dụng của bạn.

Hầu hết những thay đổi này đều ảnh hưởng đến tất cả ứng dụng, bất kể phiên bản của Android mà họ nhắm đến. Tuy nhiên, một số thay đổi chỉ ảnh hưởng đến việc nhắm mục tiêu ứng dụng Android 8.0. Để tối đa hoá rõ ràng, trang được chia thành hai phần: Thay đổi đối với tất cả ứng dụngThay đổi đối với tính năng nhắm mục tiêu ứng dụng Android 8.0.

Thay đổi đối với tất cả ứng dụng

Những thay đổi này về hành vi áp dụng cho tất cả ứng dụng khi chạy trên nền tảng Android 8.0 (API cấp 26), bất kể Cấp độ API mà đối tượng nhắm đến. Tất cả nhà phát triển nên xem những thay đổi này và sửa đổi ứng dụng để hỗ trợ chúng cho phù hợp, nếu áp dụng cho ứng dụng.

Giới hạn thực thi ở chế độ nền

Là một trong những thay đổi mà Android 8.0 (API cấp 26) giới thiệu cải thiện thời lượng pin, khi ứng dụng của bạn tham gia được lưu vào bộ nhớ đệm không có trạng thái đang hoạt động thành phần, hệ thống sẽ huỷ bỏ mọi khoá ở chế độ thức mà ứng dụng lưu giữ.

Ngoài ra, để cải thiện hiệu suất của thiết bị, hệ thống sẽ giới hạn một số của các ứng dụng không chạy ở nền trước. Cụ thể:

  • Các ứng dụng đang chạy trong nền hiện có giới hạn về mức độ thoải mái chúng có thể truy cập vào các dịch vụ nền.
  • Ứng dụng không được dùng tệp kê khai để đăng ký hầu hết các thông báo truyền phát ngầm (tức là các thông báo không nhắm mục tiêu cụ thể đến ứng dụng).

Theo mặc định, những quy định hạn chế này chỉ áp dụng cho những ứng dụng nhắm đến O. Tuy nhiên, người dùng có thể bật các hạn chế này cho bất kỳ ứng dụng nào từ màn hình Cài đặt, ngay cả khi ứng dụng không nhắm mục tiêu O.

Android 8.0 (API cấp 26) cũng có những thay đổi sau đối với các phương thức cụ thể:

  • Phương thức startService() hiện sẽ gửi một IllegalStateException nếu ứng dụng Khi nhắm đến Android 8.0, hệ thống sẽ cố gắng sử dụng phương thức đó trong trường hợp không được phép tạo dịch vụ nền.
  • Phương thức Context.startForegroundService() mới sẽ bắt đầu một dịch vụ trên nền trước. Hệ thống cho phép các ứng dụng để gọi Context.startForegroundService() ngay cả khi ứng dụng đang ở chế độ nền. Tuy nhiên, ứng dụng phải gọi phương thức startForeground() của dịch vụ đó trong vòng 5 vài giây sau khi tạo dịch vụ.

Để biết thêm thông tin, hãy xem Giới hạn thực thi ở chế độ nền.

Giới hạn quyền truy cập thông tin vị trí ở chế độ nền trên Android

Để duy trì pin, trải nghiệm người dùng và tình trạng hệ thống, ứng dụng nền sẽ nhận được thông tin cập nhật vị trí ít thường xuyên hơn khi được dùng trên một thiết bị chạy Android 8.0. Thay đổi này về hành vi ảnh hưởng đến tất cả ứng dụng nhận thông tin cập nhật vị trí, bao gồm cả Dịch vụ Google Play.

Những thay đổi này ảnh hưởng đến các API sau:

  • Trình cung cấp vị trí kết hợp (FLP)
  • Khoanh vùng địa lý
  • Đo lường GNSS
  • Trình quản lý vị trí
  • Trình quản lý Wi-Fi

Để đảm bảo ứng dụng của bạn chạy như mong đợi, hãy hoàn thành các bước sau:

  • Xem xét logic của ứng dụng và đảm bảo rằng bạn đang sử dụng thông tin vị trí mới nhất API.
  • Kiểm thử để đảm bảo rằng ứng dụng của bạn thể hiện hành vi mà bạn mong đợi cho mỗi lần sử dụng trường hợp.
  • Hãy cân nhắc sử dụng Hợp nhất Trình cung cấp vị trí (FLP) hoặc khoanh vùng địa lý để xử lý các trường hợp sử dụng phụ thuộc vào vị trí hiện tại của người dùng.

Để biết thêm thông tin về những thay đổi này, hãy xem Quyền truy cập thông tin vị trí ở chế độ nền Giới hạn.

Lối tắt ứng dụng

Android 8.0 (API cấp 26) có các thay đổi sau đây đối với lối tắt ứng dụng:

  • Số phát đi của com.android.launcher.action.INSTALL_SHORTCUT còn có bất kỳ ảnh hưởng nào đến ứng dụng của bạn hay không, vì ứng dụng hiện là ứng dụng riêng tư, ngầm ẩn truyền tin. Thay vào đó, bạn nên tạo một lối tắt ứng dụng bằng cách sử dụng requestPinShortcut() từ lớp ShortcutManager.
  • ACTION_CREATE_SHORTCUT giờ đây, ý định có thể tạo lối tắt ứng dụng mà bạn quản lý bằng cách sử dụng Lớp ShortcutManager. Ý định này cũng có thể tạo lối tắt trình chạy cũ không tương tác với ShortcutManager. Trước đây, ý định này có thể chỉ tạo các lối tắt trình chạy cũ.
  • Lối tắt được tạo bằng requestPinShortcut() và các lối tắt được tạo trong hoạt động xử lý ACTION_CREATE_SHORTCUT ý định hiện là lối tắt ứng dụng chính thức. Do đó, giờ đây các ứng dụng có thể cập nhật chúng bằng các phương thức trong ShortcutManager.
  • Phím tắt cũ giữ nguyên chức năng từ các phiên bản trước của Android, nhưng bạn phải chuyển đổi chúng thành lối tắt ứng dụng theo cách thủ công trong ứng dụng của mình.

Để tìm hiểu thêm về những thay đổi đối với lối tắt ứng dụng, hãy xem Ghim phím tắt và Hướng dẫn về tính năng cho tiện ích.

Ngôn ngữ bản địa và quốc tế hoá

Android 7.0 (API cấp 24) giới thiệu khái niệm khả năng chỉ định Ngôn ngữ danh mục mặc định, nhưng một số API tiếp tục sử dụng Locale.getDefault() chung mà không có đối số, khi đáng lẽ chúng nên sử dụng Ngôn ngữ của danh mục DISPLAY mặc định. Trong Android 8.0 (API cấp 26), các phương thức sau hiện sử dụng Locale.getDefault(Category.DISPLAY) thay vì Locale.getDefault():

Ngoài ra, Locale.getDisplayScript(Locale) quay lại Locale.getDefault() khi Đã chỉ định giá trị displayScript cho Locale đối số không khả dụng.

Các thay đổi bổ sung liên quan đến ngôn ngữ bản địa và quốc tế hoá như sau:

  • Việc gọi Currency.getDisplayName(null) sẽ gửi một NullPointerException, khớp với hành vi được ghi nhận trong tài liệu.
  • Tính năng phân tích cú pháp tên múi giờ đã thay đổi. Trước đây, Các thiết bị Android đã sử dụng giá trị đồng hồ hệ thống được lấy mẫu khi khởi động thời gian để lưu tên múi giờ vào bộ nhớ đệm dùng để phân tích cú pháp ngày lần. Kết quả là, việc phân tích cú pháp có thể bị ảnh hưởng tiêu cực nếu hệ thống xung nhịp không chính xác tại thời điểm khởi động hoặc trong các trường hợp hiếm hơn khác.

    Trong các trường hợp phổ biến, logic phân tích cú pháp sử dụng ICU và giá trị đồng hồ hệ thống hiện tại khi phân tích cú pháp tên múi giờ. Chiến dịch này thay đổi cung cấp kết quả chính xác hơn, điều này có thể khác với trước đó Các phiên bản Android khi ứng dụng của bạn sử dụng các lớp như SimpleDateFormat.

  • Android 8.0 (API cấp 26) cập nhật phiên bản ICU lên phiên bản 58.

Cửa sổ cảnh báo

Nếu một ứng dụng dùng SYSTEM_ALERT_WINDOW quyền và sử dụng một trong các loại cửa sổ sau để hiển thị cửa sổ cảnh báo phía trên các ứng dụng và cửa sổ hệ thống khác:

...thì các cửa sổ này sẽ luôn xuất hiện bên dưới những cửa sổ sử dụng Cửa sổ TYPE_APPLICATION_OVERLAY loại. Nếu một ứng dụng nhắm đến Android 8.0 (API cấp 26), thì ứng dụng đó sẽ dùng TYPE_APPLICATION_OVERLAY loại cửa sổ để hiển thị các cửa sổ cảnh báo.

Để biết thêm thông tin, hãy xem phần Các loại cửa sổ phổ biến cho phần cửa sổ cảnh báo trong phần thay đổi về hành vi cho Ứng dụng nhắm đến Android 8.0.

Nhập và điều hướng

Với sự ra đời của ứng dụng Android trên ChromeOS và các kiểu dáng lớn khác, chẳng hạn như máy tính bảng, chúng tôi thấy việc sử dụng điều hướng bằng bàn phím xuất hiện trở lại trong Ứng dụng Android. Trong Android 8.0 (API cấp 26), chúng tôi đã tái xử lý bằng cách sử dụng bàn phím làm thiết bị đầu vào điều hướng, mang lại kết quả đáng tin cậy hơn, mô hình có thể dự đoán được để điều hướng dựa trên mũi tên và thẻ.

Cụ thể, chúng tôi đã thực hiện những thay đổi sau đây đối với tiêu điểm phần tử hành vi:

  • Nếu bạn chưa xác định bất kỳ màu trạng thái tiêu điểm nào cho Đối tượng View (nền trước hoặc nền sau có thể vẽ), khung này hiện đặt màu làm nổi bật tiêu điểm mặc định cho View Tiêu điểm nổi bật này là một đối tượng có thể vẽ gợn sóng dựa trên chủ đề của hoạt động.

    Nếu bạn không muốn đối tượng View dùng chế độ mặc định này đánh dấu khi nó được lấy tiêu điểm, đặt giá trị Thuộc tính android:defaultFocusHighlightEnabled cho false trong tệp XML bố cục chứa View hoặc truyền false vào setDefaultFocusHighlightEnabled() trong logic giao diện người dùng của ứng dụng.

  • Để kiểm thử xem phương thức nhập bằng bàn phím ảnh hưởng như thế nào đến tiêu điểm của thành phần trên giao diện người dùng, bạn có thể bật Bản vẽ > Hiện tuỳ chọn cho nhà phát triển về ranh giới bố cục. Trong Android 8.0, tuỳ chọn này sẽ hiển thị dấu "X" biểu tượng trên phần tử hiện có tập trung.

Ngoài ra, tất cả các thành phần trên thanh công cụ trong Android 8.0 đều tự động cụm điều hướng trên bàn phím, giúp người dùng dễ dàng điều hướng vào và ra khỏi từng thanh công cụ như một toàn bộ.

Để tìm hiểu thêm về cách cải thiện khả năng hỗ trợ điều hướng bằng bàn phím trong cho ứng dụng của bạn, hãy đọc tài liệu Hỗ trợ Hướng dẫn về điều hướng bằng bàn phím.

Tự động điền biểu mẫu trên web

Giờ đây khi tính năng Tự động điền của Android Khung cung cấp tính năng hỗ trợ tích hợp sẵn cho chức năng tự động điền, các phương thức sau liên quan đến đối tượng WebView đã thay đổi đối với ứng dụng được cài đặt trên thiết bị chạy Android 8.0 (API cấp 26):

WebSettings
  • Chiến lược phát hành đĩa đơn getSaveFormData() phương thức hiện trả về false. Trước đây, phương thức này trả về Hãy true.
  • Gọi điện setSaveFormData() người từ chối tham gia không còn tác dụng.
WebViewDatabase
  • Gọi điện clearFormData() người từ chối tham gia không còn tác dụng.
  • Chiến lược phát hành đĩa đơn hasFormData() phương thức hiện sẽ trả về false. Trước đây, phương thức này trả về true khi biểu mẫu chứa dữ liệu.

Hỗ trợ tiếp cận

Android 8.0 (API cấp 26) có các thay đổi sau đây đối với tính năng hỗ trợ tiếp cận:

  • Khung hỗ trợ tiếp cận hiện chuyển đổi tất cả các cử chỉ nhấn đúp thành ACTION_CLICK hành động. Thay đổi này cho phép TalkBack hoạt động giống các tính năng khác dịch vụ hỗ trợ tiếp cận.

    Nếu các đối tượng View của ứng dụng sử dụng thao tác chạm tuỳ chỉnh xử lý, bạn nên xác minh rằng chúng vẫn hoạt động với TalkBack. Bạn có thể bạn chỉ cần đăng ký trình xử lý lượt nhấp mà View của bạn sử dụng. Nếu TalkBack vẫn không nhận ra các cử chỉ được thực hiện trên những thiết bị này View đối tượng, ghi đè performAccessibilityAction()

  • Các dịch vụ hỗ trợ tiếp cận hiện đã biết được tất cả ClickableSpan thực thể trong ứng dụng của bạn Đối tượng TextView.

Để tìm hiểu thêm về cách giúp ứng dụng của bạn dễ tiếp cận hơn, hãy xem Accessibility (Trợ năng).

Kết nối mạng và HTTP(S)

Android 8.0 (API cấp 26) có các thay đổi sau đây về hành vi đối với kết nối mạng và kết nối HTTP(S):

  • Các yêu cầu OPTIONS không có nội dung có Content-Length: 0 . Trước đây, chúng không có tiêu đề Content-Length.
  • HttpURLConnection chuẩn hoá URL chứa đường dẫn trống bằng cách thêm vào dấu gạch chéo sau tên máy chủ hoặc cơ quan quản lý có dấu gạch chéo. Ví dụ: chuyển đổi http://example.com thành http://example.com/
  • Bộ chọn proxy tuỳ chỉnh được đặt qua ProxySelector.setDefault() chỉ nhắm mục tiêu địa chỉ (lược đồ, máy chủ và cổng) của URL được yêu cầu. Do đó, lựa chọn proxy chỉ có thể dựa trên các giá trị đó. Một URL được chuyển đến bộ chọn proxy tuỳ chỉnh không bao gồm đường dẫn, tham số truy vấn hoặc mảnh.
  • URI không được chứa nhãn trống.

    Trước đây, nền tảng này đã hỗ trợ giải pháp chấp nhận nhãn trống trong tên máy chủ lưu trữ, là việc sử dụng URI bất hợp pháp. Giải pháp này dành cho khả năng tương thích với các bản phát hành libcore cũ hơn. Nhà phát triển sử dụng API sẽ không thấy thông báo ADB: "URI example..com có nhãn trống trong tên máy chủ. Định dạng này không đúng định dạng và sẽ không được chấp nhận trong các thiết bị Android trong tương lai bản phát hành mới". Android 8.0 sẽ xoá giải pháp này; hệ thống trả về rỗng cho các URI không đúng định dạng.

  • Hoạt động triển khai HttpsURLConnection của Android 8.0 không thực hiện dự phòng phiên bản giao thức TLS/SSL không an toàn.
  • Việc xử lý các kết nối HTTP(S) tạo đường hầm đã thay đổi như sau:
    • Khi tạo đường hầm cho kết nối HTTPS qua kết nối, hệ thống đặt chính xác số cổng (:443) trong dòng Máy chủ khi gửi thông tin này đến máy chủ trung gian. Trước đây, cổng chỉ xuất hiện trong dòng CONNECT.
    • Hệ thống sẽ không gửi tác nhân người dùng và lệnh cấp phép proxy nữa từ một yêu cầu được tạo trong đường hầm đến máy chủ proxy.

      Hệ thống sẽ không gửi tiêu đề cấp quyền proxy trên đường hầm Http(s)URLConnection tới proxy khi thiết lập đường hầm. Thay vào đó, hệ thống sẽ tạo một tiêu đề ủy quyền proxy, và gửi nó đến proxy khi proxy đó gửi HTTP 407 để phản hồi yêu cầu ban đầu.

      Tương tự, hệ thống không còn sao chép tiêu đề tác nhân người dùng nữa từ yêu cầu được tạo đường hầm đến yêu cầu proxy thiết lập đường hầm. Thay vào đó, thư viện sẽ tạo tiêu đề cho tác nhân người dùng của bạn.

  • send(java.net.DatagramPacket) phương thức sẽ gửi một SocketException nếu connect() được thực thi trước đó không thành công.
    • DatagramSocket.connect() đặt pendingSocketException nếu có lỗi nội bộ. Trước Android 8.0, recv() tiếp theo đã gửi một SocketException mặc dù lệnh gọi send() đã thành công. Để đảm bảo tính nhất quán, cả hai lệnh gọi hiện đều gửi một SocketException.
  • InetAddress.isReachable() thử ICMP trước khi quay lại Echo của TCP giao thức.
    • Một số máy chủ lưu trữ chặn cổng 7 (TCP Echo), chẳng hạn như google.com, có thể giờ đây có thể truy cập được nếu chúng chấp nhận giao thức ICMP Echo.
    • Đối với các máy chủ thực sự không thể truy cập, thay đổi này có nghĩa là thời gian trước khi cuộc gọi được trả về.

Bluetooth

Android 8.0 (API cấp 26) thực hiện các thay đổi sau đối với độ dài của dữ liệu mà ScanRecord.getBytes() phương thức truy xuất:

  • Phương thức getBytes() không đưa ra giả định nào số byte đã nhận. Do đó, ứng dụng không nên dựa vào số byte tối thiểu hoặc tối đa được trả về. Thay vào đó, họ nên đánh giá độ dài của mảng thu được.
  • Các thiết bị tương thích với Bluetooth 5 có thể trả về thời lượng dữ liệu vượt quá tối đa trước đó là ~60 byte.
  • Nếu thiết bị từ xa không cung cấp phản hồi quét thì có kích thước nhỏ hơn 60 byte cũng có thể được trả lại.

Khả năng kết nối liền mạch

Android 8.0 (API cấp 26) cải tiến một số chế độ Cài đặt Wi-Fi để dễ chọn hơn mạng Wi-Fi mang lại trải nghiệm người dùng tốt nhất. Các thay đổi cụ thể bao gồm:

  • Cải thiện độ ổn định và độ tin cậy.
  • Giao diện người dùng dễ đọc hơn.
  • Một trình đơn Lựa chọn ưu tiên về Wi-Fi hợp nhất.
  • Trên các thiết bị tương thích, tự động kích hoạt Wi-Fi khi mạng đã lưu chất lượng cao đang ở gần đây.

Bảo mật

Android 8.0 bao gồm các tính năng bảo mật liên quan đến các thay đổi:

  • Nền tảng này không còn hỗ trợ SSLv3.
  • Khi thiết lập kết nối HTTPS với máy chủ không chính xác triển khai quá trình thương lượng phiên bản giao thức TLS, HttpsURLConnection không thử giải pháp này nữa quay lại phiên bản giao thức TLS trước đó và thử lại.
  • Android 8.0 (API cấp 26) áp dụng công nghệ Điện toán bảo mật (SECCOMP) lọc tất cả các ứng dụng. Danh sách các lệnh gọi hệ thống được phép chỉ bao gồm được phơi nhiễm thông qua công nghệ sinh học. Mặc dù có một số lệnh gọi hệ thống khác được cung cấp để đảm bảo khả năng tương thích ngược.
  • Các đối tượng WebView của ứng dụng hiện chạy trong đa tiến trình . Nội dung web được xử lý theo một quy trình riêng biệt với chứa quy trình của ứng dụng để tăng cường bảo mật.
  • Bạn không còn có thể cho rằng tệp APK nằm trong các thư mục có tên kết thúc trong -1 hoặc -2. Ứng dụng nên sử dụng sourceDir để nhận và không trực tiếp dựa vào định dạng thư mục.
  • Để biết thông tin về các tính năng nâng cao bảo mật liên quan đến việc sử dụng mã gốc hãy xem Thư viện gốc.

Ngoài ra, Android 8.0 (API cấp 26) ra mắt các thay đổi sau liên quan đến việc cài đặt ứng dụng không xác định từ các nguồn không xác định:

  • Giá trị của chế độ cài đặt cũ INSTALL_NON_MARKET_APPS hiện là luôn là 1. Để xác định xem một nguồn không xác định có thể cài đặt các ứng dụng bằng trình cài đặt gói, bạn nên sử dụng giá trị trả về của canRequestPackageInstalls().
  • Nếu bạn cố thay đổi giá trị của INSTALL_NON_MARKET_APPS đang sử dụng setSecureSetting(), một UnsupportedOperationException sẽ được gửi. Ngăn người dùng cài đặt ứng dụng không xác định bằng ứng dụng không xác định nguồn, thay vào đó, bạn nên áp dụng DISALLOW_INSTALL_UNKNOWN_SOURCES người dùng .
  • Các hồ sơ được quản lý được tạo trên các thiết bị chạy Android 8.0 (API cấp 26) sẽ tự động có DISALLOW_INSTALL_UNKNOWN_SOURCES người dùng đã bật hạn chế. Đối với hồ sơ được quản lý hiện có trên những thiết bị đã nâng cấp lên Android 8.0, DISALLOW_INSTALL_UNKNOWN_SOURCES người dùng quy định hạn chế này sẽ tự động được bật trừ phi chủ sở hữu trang doanh nghiệp đã nêu rõ đã tắt hạn chế này (trước khi nâng cấp) bằng cách cài đặt INSTALL_NON_MARKET_APPS thành 1.

Để biết thêm thông tin về cách cài đặt ứng dụng không xác định, hãy xem Ứng dụng không xác định Hướng dẫn cài đặt quyền.

Để biết thêm nguyên tắc về cách giúp ứng dụng của bạn an toàn hơn, hãy xem Bảo mật dành cho nhà phát triển Android.

Quyền riêng tư

Android 8.0 (API cấp 26) đưa ra các lợi ích liên quan đến quyền riêng tư sau đây các thay đổi đối với nền tảng.

  • Nền tảng hiện xử lý các giá trị nhận dạng theo cách khác.
    • Đối với những ứng dụng được cài đặt trước phiên bản OTA Android 8.0 (API cấp 26) (API cấp 26), giá trị của ANDROID_ID không thay đổi trừ khi bị gỡ cài đặt rồi cài đặt lại sau OTA. Để duy trì các giá trị trên gỡ cài đặt sau OTA, nhà phát triển có thể liên kết các giá trị cũ và mới bằng cách sử dụng Sao lưu khoá/giá trị.
    • Đối với ứng dụng được cài đặt trên thiết bị chạy Android 8.0, giá trị của ANDROID_ID hiện đã thuộc phạm vi theo khoá ký ứng dụng, cũng như trên mỗi người dùng. Giá trị của ANDROID_ID là duy nhất cho từng tổ hợp khoá ký ứng dụng, người dùng và thiết bị. Do đó, các ứng dụng có nhiều khoá ký chạy trên cùng một thiết bị không còn thấy cùng một mã nhận dạng Android (ngay cả đối với cùng một người dùng).
    • Giá trị của ANDROID_ID không thay đổi khi gỡ cài đặt hoặc cài đặt lại gói, miễn là khoá ký là giống nhau (và ứng dụng chưa được cài đặt trước khi có OTA đến Android 8.0).
    • Giá trị của ANDROID_ID không thay đổi ngay cả khi bản cập nhật hệ thống làm cho khoá ký gói thay đổi.
    • Trên những thiết bị vận chuyển bằng Dịch vụ Google Play và Mã nhận dạng cho quảng cáo, bạn phải sử dụng Mã nhận dạng cho quảng cáo. Một hệ thống chuẩn, đơn giản để kiếm tiền từ ứng dụng, Mã nhận dạng cho quảng cáo là một mã nhận dạng duy nhất mà người dùng có thể đặt lại dành cho quảng cáo. Được cung cấp thông qua Dịch vụ Google Play.

      Các nhà sản xuất thiết bị khác nên tiếp tục để cung cấp ANDROID_ID.

  • Việc truy vấn thuộc tính hệ thống net.hostname sẽ tạo ra giá trị rỗng kết quả.

Ghi nhật ký các trường hợp ngoại lệ chưa nắm bắt được

Nếu một ứng dụng cài đặt một Thread.UncaughtExceptionHandler và ứng dụng đó không gọi tới Thread.UncaughtExceptionHandler mặc định, hệ thống sẽ không tắt ứng dụng khi trường hợp ngoại lệ chưa nắm bắt xảy ra. Giá từ Android 8.0 (API cấp 26), hệ thống ghi lại dấu vết ngăn xếp ngoại lệ trong tình huống cụ thể; trong các phiên bản trước đây của nền tảng, hệ thống sẽ không phải đã ghi lại dấu vết ngăn xếp ngoại lệ.

Bạn nên sử dụng Thread.UncaughtExceptionHandler tuỳ chỉnh các triển khai luôn gọi qua để trình xử lý mặc định; các ứng dụng tuân theo đề xuất này không bị ảnh hưởng bởi thay đổi trong Android 8.0.

Thay đổi chữ ký findViewById()

Giờ đây, tất cả thực thể của phương thức findViewById() sẽ trả về <T extends View> T thay vì View. Sự thay đổi này có những tác động sau:

  • Điều này có thể khiến mã hiện tại có loại dữ liệu trả về không rõ ràng, chẳng hạn như nếu có cả someMethod(View)someMethod(TextView) nhận kết quả của cuộc gọi tới findViewById().
  • Khi sử dụng ngôn ngữ nguồn Java 8, bạn phải truyền rõ ràng tới View khi loại dữ liệu trả về không bị giới hạn (ví dụ: assertNotNull(findViewById(...)).someViewMethod())
  • Ghi đè các phương thức findViewById() không phải cuối cùng (cho ví dụ: Activity.findViewById()) sẽ cần trả về đã cập nhật loại.

Thay đổi số liệu thống kê sử dụng của trình cung cấp danh bạ

Trong các phiên bản Android trước, thành phần Trình cung cấp danh bạ cho phép nhà phát triển nhận dữ liệu sử dụng cho từng người liên hệ. Dữ liệu sử dụng này hiển thị thông tin của từng địa chỉ email và từng số điện thoại được liên kết với một người liên hệ, kể cả số lần người liên hệ đó được liên hệ và lần cuối cùng người liên hệ được liên hệ. Ứng dụng yêu cầu READ_CONTACTS có thể đọc dữ liệu này.

Các ứng dụng vẫn có thể đọc dữ liệu này nếu yêu cầu READ_CONTACTS quyền. Trong Android 8.0 (API cấp 26) trở lên, các truy vấn để trả về dữ liệu sử dụng ước lượng thay vì giá trị chính xác. Hệ thống Android duy trì các giá trị chính xác trong nội bộ, vì vậy thay đổi này không ảnh hưởng đến API tự động hoàn thành.

Thay đổi này về hành vi ảnh hưởng đến các tham số truy vấn sau:

Xử lý việc thu thập

AbstractCollection.removeAll()AbstractCollection.retainAll() hiện luôn gửi một NullPointerException; trước đây, phương thức NullPointerException không được gửi khi bộ sưu tập là trống. Thay đổi này giúp hành vi của bạn phù hợp với tài liệu.

Android Enterprise

Android 8.0 (API cấp 26) thay đổi hoạt động của một số API và tính năng dành cho các ứng dụng dành cho doanh nghiệp, bao gồm cả thiết bị đơn vị kiểm soát chính sách (DPC). Các thay đổi bao gồm:

  • Các hành vi mới giúp ứng dụng hỗ trợ hồ sơ công việc trên các thiết bị được quản lý toàn bộ.
  • Những thay đổi về việc xử lý bản cập nhật hệ thống, xác minh ứng dụng và xác thực đối với tăng tính toàn vẹn của thiết bị và hệ thống.
  • Những cải tiến đối với trải nghiệm người dùng liên quan đến việc cấp phép, thông báo, Màn hình Gần đây và VPN luôn bật.

Để xem tất cả thay đổi của doanh nghiệp trong Android 8.0 (API cấp 26) và tìm hiểu cách chúng có thể ảnh hưởng đến ứng dụng của bạn, hãy đọc Android trong Enterprise.

Ứng dụng nhắm đến Android 8.0

Những thay đổi về hành vi này chỉ áp dụng cho các ứng dụng đang nhắm mục tiêu Android 8.0 (API cấp 26) trở lên. Ứng dụng biên dịch trên Android 8.0, hoặc thiết lập targetSdkVersion thành Android 8.0 trở lên phải sửa đổi ứng dụng của họ để hỗ trợ những hành vi này đúng cách, nếu phù hợp.

Cửa sổ cảnh báo

Ứng dụng sử dụng SYSTEM_ALERT_WINDOW quyền không thể dùng các loại cửa sổ sau để hiển thị cửa sổ cảnh báo nữa phía trên các ứng dụng và cửa sổ hệ thống khác:

Thay vào đó, ứng dụng phải dùng một loại cửa sổ mới có tên là TYPE_APPLICATION_OVERLAY.

Khi sử dụng Cửa sổ TYPE_APPLICATION_OVERLAY nhập để hiển thị cửa sổ cảnh báo cho ứng dụng của bạn, hãy giữ các đặc điểm sau về loại cửa sổ mới:

  • Cửa sổ cảnh báo của một ứng dụng luôn xuất hiện dưới các cửa sổ hệ thống quan trọng, chẳng hạn như làm thanh trạng thái và IME.
  • Hệ thống có thể di chuyển hoặc đổi kích thước các cửa sổ sử dụng TYPE_APPLICATION_OVERLAY loại cửa sổ để cải thiện bản trình bày trên màn hình.
  • Bằng cách mở ngăn thông báo, người dùng có thể truy cập vào phần cài đặt để chặn ngừng hiển thị các cửa sổ cảnh báo hiển thị bằng cách sử dụng TYPE_APPLICATION_OVERLAY loại cửa sổ.

Thông báo về việc thay đổi nội dung

Android 8.0 (API cấp 26) thay đổi cách thức ContentResolver.notifyChange()registerContentObserver(Uri, boolean, ContentObserver) hoạt động với các ứng dụng nhắm đến Android 8.0.

Các API này hiện yêu cầu ContentProvider hợp lệ được xác định cho thẩm quyền trong tất cả URI. Việc xác định một ContentProvider hợp lệ kèm theo các quyền liên quan sẽ giúp bảo vệ ứng dụng của bạn khỏi những thay đổi về nội dung trước các ứng dụng độc hại, đồng thời ngăn bạn từ việc rò rỉ dữ liệu có thể riêng tư cho các ứng dụng độc hại.

Xem tiêu điểm

Các đối tượng View có thể nhấp hiện cũng có thể được lấy làm tâm điểm mặc định. Nếu bạn muốn đối tượng View có thể nhấp vào được nhưng không thể nhấp vào có thể làm tâm điểm, đặt giá trị Thuộc tính android:focusable cho false trong bố cục Tệp XML chứa View hoặc truyền vào false vào setFocusable() trong giao diện người dùng của ứng dụng logic.

So khớp tác nhân người dùng trong phát hiện trình duyệt

Android 8.0 (API cấp 26) trở lên bao gồm chuỗi giá trị nhận dạng bản dựng OPR. Một số kết quả trùng khớp về mẫu có thể khiến logic phát hiện trình duyệt xác định sai một trình duyệt không phải Opera là Opera. Ví dụ về trường hợp khớp mẫu như vậy:

if(p.match(/OPR/)){k="Opera";c=p.match(/OPR\/(\d+.\d+)/);n=new Ext.Version(c[1])}

Để tránh các vấn đề phát sinh từ việc nhận dạng sai như vậy, hãy sử dụng một chuỗi khác OPR làm phương thức khớp mẫu cho trình duyệt Opera.

Bảo mật

Những thay đổi sau ảnh hưởng đến tính bảo mật trong Android 8.0 (API cấp 26):

  • Nếu cấu hình bảo mật mạng của ứng dụng tuỳ chọn không hỗ trợ lưu lượng truy cập qua văn bản thô, Đối tượng WebView không thể truy cập vào các trang web qua HTTP. Một Thay vào đó, đối tượng WebView phải sử dụng HTTPS.
  • Cài đặt hệ thống Cho phép nguồn không xác định đã bị loại bỏ; trong địa điểm, quyền Cài đặt ứng dụng không xác định quản lý lượt cài đặt ứng dụng không xác định từ nguồn không xác định. Để tìm hiểu thêm về quyền mới này, hãy xem Ứng dụng không xác định Hướng dẫn cài đặt quyền.

Để biết thêm nguyên tắc về cách giúp ứng dụng của bạn an toàn hơn, hãy xem Bảo mật dành cho nhà phát triển Android.

Quyền truy cập vào tài khoản và khả năng phát hiện tài khoản

Trong Android 8.0 (API cấp 26), ứng dụng không thể truy cập được nữa vào tài khoản người dùng, trừ phi trình xác thực sở hữu tài khoản đó hoặc người dùng cấp quyền truy cập đó. Chiến lược phát hành đĩa đơn Quyền GET_ACCOUNTS không còn đủ nữa. Để được cấp quyền truy cập vào một tài khoản, ứng dụng phải hoặc sử dụng AccountManager.newChooseAccountIntent() hoặc ứng dụng . Sau khi có quyền truy cập vào tài khoản, ứng dụng có thể gọi AccountManager.getAccounts() để truy cập vào các tài nguyên này.

Ngừng sử dụng Android 8.0 LOGIN_ACCOUNTS_CHANGED_ACTION. Chiến dịch Quảng cáo ứng dụng nên sử dụng addOnAccountsUpdatedListener() để nhận thông tin cập nhật về tài khoản trong thời gian chạy.

Để biết thông tin về các API và phương thức mới được thêm vào để truy cập vào tài khoản và tiềm năng, hãy xem Truy cập tài khoản và Khả năng phát hiện trong phần API mới của tài liệu này.

Quyền riêng tư

Những thay đổi sau ảnh hưởng đến quyền riêng tư trong Android 8.0 (API cấp 26).

  • Các thuộc tính hệ thống là net.dns1, net.dns2, net.dns3net.dns4 không còn tồn tại nữa sẵn có, một thay đổi giúp cải thiện quyền riêng tư trên nền tảng.
  • Để có được thông tin mạng như máy chủ DNS, ứng dụng có ACCESS_NETWORK_STATE có thể đăng ký NetworkRequest hoặc Đối tượng NetworkCallback. Các lớp này có trong Android 5.0 (API cấp 21) trở lên.
  • Ngừng sử dụng Build.SERIAL. Nếu cần biết số sê-ri phần cứng, thì ứng dụng nên thay thế hãy sử dụng phương thức Build.getSerial() mới. Phương thức này yêu cầu READ_PHONE_STATE quyền.
  • API LauncherApps không còn cho phép hồ sơ công việc nữa để nhận thông tin về hồ sơ chính. Khi người dùng đang làm việc hồ sơ, API LauncherApps sẽ hoạt động như thể không có ứng dụng nào được cài đặt trong các hồ sơ khác trong cùng một nhóm hồ sơ. Như trước đây, việc cố gắng truy cập vào các hồ sơ không liên quan sẽ gây ra lỗi SecurityExceptions.

Quyền

Trước Android 8.0 (API cấp 26), nếu ứng dụng yêu cầu cấp quyền trong thời gian chạy và quyền đã được cấp, thì hệ thống cũng không chính xác đã cấp cho ứng dụng các quyền còn lại thuộc cùng một ứng dụng nhóm quyền và đã được đăng ký trong tệp kê khai.

Đối với các ứng dụng nhắm đến Android 8.0, hành vi này đã được đã sửa. Ứng dụng chỉ được cấp các quyền mà ứng dụng đã chỉ định rõ ràng đã yêu cầu. Tuy nhiên, sau khi người dùng cấp quyền cho ứng dụng, tất cả các yêu cầu tiếp theo về các quyền trong nhóm quyền đó được cấp tự động.

Ví dụ: giả sử một ứng dụng liệt kê cả READ_EXTERNAL_STORAGEWRITE_EXTERNAL_STORAGE trong tệp kê khai. Ứng dụng yêu cầu READ_EXTERNAL_STORAGE và mà người dùng cấp. Nếu ứng dụng nhắm đến API cấp 25 trở xuống, thì hệ thống cũng cấp WRITE_EXTERNAL_STORAGE cùng lúc vì thuộc cùng một nhóm quyền STORAGE và cũng thuộc đã đăng ký trong tệp kê khai. Nếu ứng dụng nhắm đến Android 8.0 (API cấp 26), thì hệ thống sẽ cấp chỉ READ_EXTERNAL_STORAGE vào thời điểm đó; tuy nhiên, nếu sau đó ứng dụng yêu cầu WRITE_EXTERNAL_STORAGE, hệ thống sẽ ngay lập tức cấp đặc quyền đó mà không nhắc người dùng.

Nội dung nghe nhìn

  • Khung này có thể hoạt động tự động giảm âm thanh . Trong trường hợp này, khi một ứng dụng khác yêu cầu lấy tiêu điểm bằng AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, ứng dụng có trọng tâm làm giảm số lượng nhưng thường không nhận được onAudioFocusChange() gọi lại và sẽ không mất quyền phát âm thanh. Có các API mới để ghi đè hành vi này đối với các ứng dụng cần tạm dừng thay vì giảm số lượng.
  • Khi người dùng nhận cuộc gọi điện thoại, luồng nội dung nghe nhìn đang hoạt động sẽ tắt tiếng trong khoảng thời gian .
  • Mọi API liên quan đến âm thanh đều phải sử dụng AudioAttributes thay vì các loại luồng âm thanh để mô tả trường hợp sử dụng phát lại âm thanh. Tiếp tục sử dụng các loại luồng âm thanh chỉ cho các nút điều chỉnh âm lượng. Các cách sử dụng khác của các loại luồng vẫn hoạt động (ví dụ: đối số streamType cho thuộc tính không dùng nữa hàm khởi tạo AudioTrack), nhưng hệ thống ghi lại đây là lỗi.
  • Khi sử dụng AudioTrack, nếu ứng dụng yêu cầu bộ đệm âm thanh đủ lớn, khung này sẽ cố gắng sử dụng đầu ra vùng đệm sâu (nếu có).
  • Trong Android 8.0 (API cấp 26), cách xử lý sự kiện nút đa phương tiện sẽ khác:
    1. Xử lý các nút nội dung nghe nhìn trong một hoạt động trên giao diện người dùng không thay đổi: các hoạt động trên nền trước vẫn được ưu tiên khi xử lý sự kiện nút nội dung nghe nhìn.
    2. Nếu hoạt động trên nền trước không xử lý sự kiện nút nội dung nghe nhìn, thì hệ thống sẽ định tuyến sự kiện đó vào ứng dụng phát âm thanh cục bộ gần đây nhất. Trạng thái hoạt động, cờ và chế độ phát trạng thái của phiên phát nội dung đa phương tiện không được xem xét khi xác định ứng dụng nào nhận nội dung nghe nhìn sự kiện nút.
    3. Nếu phiên đa phương tiện của ứng dụng đã bị huỷ bỏ, hệ thống sẽ gửi sự kiện nút đa phương tiện đến MediaButtonReceiver nếu có.
    4. Đối với mỗi trường hợp khác, hệ thống sẽ loại bỏ sự kiện nút nội dung nghe nhìn.

Thư viện gốc

Trong ứng dụng nhắm đến Android 8.0 (API cấp 26), thư viện gốc không có tải lâu hơn nếu chúng chứa bất kỳ phân đoạn tải nào vừa có thể ghi và tệp thực thi. Một số ứng dụng có thể ngừng hoạt động do thay đổi này nếu chúng thư viện gốc có phân đoạn tải không chính xác. Đây là một biện pháp tăng cường bảo mật.

Để biết thêm thông tin, hãy xem Phân đoạn có thể ghi và có thể thực thi.

Các thay đổi về trình liên kết gắn liền với cấp độ API mà ứng dụng nhắm mục tiêu. Nếu có là một thay đổi về trình liên kết ở cấp độ API được nhắm mục tiêu thì ứng dụng không thể tải thư viện. Nếu bạn đang nhắm mục tiêu cấp API thấp hơn cấp độ API nơi xảy ra thay đổi trình liên kết, logcat cho thấy một cảnh báo.

Xử lý việc thu thập

Trong Android 8.0 (API cấp 26), Collections.sort() được triển khai trên đầu List.sort(). Ngược lại đúng trong Android 7.x (API cấp 24 và 25): Phương thức triển khai mặc định của List.sort() có tên là Collections.sort().

Thay đổi này cho phép Collections.sort() để tận dụng List.sort() được tối ưu hoá cụ thể, nhưng có những hạn chế sau:

  • Việc triển khai List.sort() không được gọi Collections.sort(), vì làm như vậy sẽ dẫn đến tràn ngăn xếp do đệ quy vô hạn. Thay vào đó, nếu bạn muốn hành vi mặc định trong quá trình triển khai List, bạn nên tránh ghi đè sort()

    Nếu một lớp mẹ triển khai sort() không phù hợp, thì đó là thường có thể ghi đè List.sort() với cách triển khai được xây dựng dựa trên List.toArray(), Arrays.sort()ListIterator.set(). Ví dụ:

    @Override
    public void sort(Comparator<? super E> c) {
      Object[] elements = toArray();
      Arrays.sort(elements, c);
      ListIterator<E> iterator = (ListIterator<Object>) listIterator();
      for (Object element : elements) {
        iterator.next();
        iterator.set((E) element);
      }
    }
    

    Trong hầu hết các trường hợp, bạn cũng có thể ghi đè List.sort() có trong đó uỷ quyền cho các giá trị mặc định khác nhau tuỳ thuộc vào cấp độ API. Ví dụ:

    @Override
    public void sort(Comparator<? super E> comparator) {
      if (Build.VERSION.SDK_INT <= 25) {
        Collections.sort(this);
      } else {
        super.sort(comparator);
      }
    }
    

    Nếu bạn thực hiện việc sau chỉ vì bạn muốn có sort() có sẵn ở mọi cấp độ API, hãy cân nhắc đặt một tên riêng biệt cho phương thức này chẳng hạn như sortCompat(), thay vì ghi đè sort().

  • Collections.sort() hiện được tính là sửa đổi cấu trúc ở Liệt kê các phương thức triển khai gọi sort(). Ví dụ: trong phiên bản của nền tảng trước Android 8.0 (API cấp 26), lặp lại hơn ArrayList và gọi sort() trên đó một phần trong quá trình lặp lại sẽ gửi ConcurrentModificationException sắp xếp xong chưa bằng cách gọi List.sort(). Collections.sort() không gửi một trường hợp ngoại lệ.

    Thay đổi này giúp hành vi của nền tảng trở nên nhất quán hơn: phương pháp tiếp cận hiện dẫn đến ConcurrentModificationException.

Hành vi tải lớp

Android 8.0 (API cấp 26) kiểm tra để đảm bảo rằng trình tải lớp không phá vỡ các giả định của thời gian chạy khi tải các lớp mới. Các bước kiểm tra này thực hiện xem lớp có được tham chiếu từ Java hay không (từ forName()), Mã byte Dalvik hoặc JNI. Nền tảng này không chặn các lệnh gọi trực tiếp từ Java đến Phương thức loadClass(), cũng như không kiểm tra kết quả của các cuộc gọi đó. Hành vi này sẽ không ảnh hưởng đến chức năng của những ứng dụng có hành vi tốt trình tải lớp.

Nền tảng sẽ kiểm tra để đảm bảo rằng chỉ số mô tả của lớp mà trình tải lớp trả về khớp với chỉ số mô tả dự kiến. Nếu mô tả được trả về không khớp, nền tảng sẽ tạo ra lỗi NoClassDefFoundError và lưu trữ trong ngoại lệ, thông báo chi tiết về sự khác biệt.

Nền tảng này cũng kiểm tra để đảm bảo rằng chỉ số mô tả của các lớp được yêu cầu là hợp lệ. Chiến dịch này kiểm tra các lệnh gọi JNI tải gián tiếp các lớp như GetFieldID(), truyền mã mô tả không hợp lệ đến các lớp đó. Ví dụ: một trường có chữ ký Không tìm thấy java/lang/String vì chữ ký đó không hợp lệ; dữ liệu sẽ là Ljava/lang/String;.

Lệnh này khác với lệnh gọi JNI đến FindClass() trong đó java/lang/String là tên đủ điều kiện hợp lệ.

Android 8.0 (API cấp 26) không hỗ trợ việc có nhiều trình tải lớp cố gắng xác định các lớp bằng cách sử dụng cùng một đối tượng DexFile. Nếu bạn cố gắng làm như vậy, thì môi trường thời gian chạy Android sẽ gửi một InternalError lỗi với thông báo "Cố gắng đăng ký tệp dex <filename> với nhiều trình tải lớp".

API DexFile hiện không còn được dùng nữa và bạn nên sử dụng một trong các trình tải lớp nền tảng, bao gồm PathClassLoader hoặc BaseDexClassLoader.

Lưu ý: Bạn có thể tạo nhiều trình tải lớp tham chiếu đến cùng một vùng chứa tệp APK hoặc JAR từ hệ thống tệp. Việc làm như vậy thường không sẽ dẫn đến mức hao tổn bộ nhớ nhiều: Nếu tệp DEX trong vùng chứa được lưu trữ thay vì được nén, nền tảng có thể thực hiện thao tác mmap trên chúng thay vì trực tiếp trích xuất chúng. Tuy nhiên, nếu nền tảng phải trích xuất tệp DEX từ vùng chứa, việc tham chiếu tệp DEX theo cách này có thể tốn nhiều bộ nhớ.

Trong Android, tất cả trình tải lớp đều có khả năng tải song song. Khi nhiều luồng chạy đua để tải cùng một lớp bằng cùng một lớp trình tải, luồng đầu tiên để hoàn tất thao tác sẽ thắng và kết quả được dùng cho các chuỗi khác. Hành vi này xảy ra bất kể trình tải lớp đã trả về cùng một lớp, trả về một lớp khác hoặc gửi một ngoại lệ. Nền tảng này sẽ tự động bỏ qua các ngoại lệ như vậy.

Thận trọng: Trong các phiên bản của nền tảng thấp hơn Android 8.0 (API cấp 26), việc phá vỡ các giả định này có thể dẫn đến việc xác định lớp nhiều lần, lỗi vùng nhớ khối xếp do nhầm lẫn về lớp, và các tác động không mong muốn khác.