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ụng và Thay đổ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
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ộtIllegalStateException
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ọiContext.startForegroundService()
ngay cả khi ứng dụng đang ở chế độ nền. Tuy nhiên, ứng dụng phải gọi phương thứcstartForeground()
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ụngrequestPinShortcut()
từ lớpShortcutManager
. 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ớpShortcutManager
. Ý đị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ớiShortcutManager
. 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 trongShortcutManager
. - 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ộtNullPointerException
, 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 choView
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ínhandroid:defaultFocusHighlightEnabled
chofalse
trong tệp XML bố cục chứaView
hoặc truyềnfalse
vàosetDefaultFocusHighlightEnabled()
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ãytrue
. - Gọi điện
setSaveFormData()
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
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.
- Gọi điện
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àyView
đố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ượngTextView
.
Để 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ànhhttp://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ủacanRequestPackageInstalls()
. - Nếu bạn cố thay đổi giá trị của
INSTALL_NON_MARKET_APPS
đang sử dụngsetSecureSetting()
, mộtUnsupportedOperationException
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ụngDISALLOW_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 đặtINSTALL_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ủaANDROID_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
.
-
Đố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
- 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)
vàsomeMethod(TextView)
nhận kết quả của cuộc gọi tớifindViewById()
. - 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()
và 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()
và 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ượngWebView
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.dns3
vànet.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ượngNetworkCallback
. 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ầuREAD_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ơ, APILauncherApps
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_STORAGE
và
WRITE_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 đượconAudioFocusChange()
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ạoAudioTrack
), 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:
- 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.
- 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.
- 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ó. - Đố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ọiCollections.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 khaiList
, 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ênList.toArray()
,Arrays.sort()
và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ọisort()
. 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ơnArrayList
và gọisort()
trên đó một phần trong quá trình lặp lại sẽ gửiConcurrentModificationException
sắp xếp xong chưa bằng cách gọiList.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.