Câu hỏi thường gặp

Google đã sử dụng OTA A/B trên thiết bị nào chưa?

Có. Tên tiếp thị cho tính năng cập nhật A/B là cập nhật liền mạch. Điện thoại Pixel và Pixel XL từ tháng 10 năm 2016 được vận chuyển bằng A/B và tất cả Chromebook đều sử dụng cùng một cách triển khai update_engine của A/B. Việc triển khai mã nền tảng cần thiết là công khai trong Android 7.1 trở lên.

Tại sao OTA A/B lại tốt hơn?

OTA A/B mang lại trải nghiệm tốt hơn cho người dùng khi cập nhật. Số liệu đo lường từ các bản cập nhật bảo mật hằng tháng cho thấy tính năng này đã thành công: Kể từ tháng 5 năm 2017, 95% chủ sở hữu Pixel đang chạy bản cập nhật bảo mật mới nhất sau một tháng so với 87% người dùng Nexus, và người dùng Pixel cập nhật sớm hơn người dùng Nexus. Việc không cập nhật được các khối trong quá trình OTA sẽ không còn khiến thiết bị không khởi động được nữa; cho đến khi hình ảnh hệ thống mới khởi động thành công, Android vẫn có thể quay lại hình ảnh hệ thống đang hoạt động trước đó.

system_other là gì?

Ứng dụng được lưu trữ trong các tệp .apk, thực chất là các tệp lưu trữ ZIP. Mỗi tệp .apk có một hoặc nhiều tệp .dex chứa mã byte Dalvik di động. Tệp .odex (.dex được tối ưu hoá) nằm riêng biệt với tệp .apk và có thể chứa mã máy dành riêng cho thiết bị. Nếu có tệp .odex, Android có thể chạy các ứng dụng ở tốc độ biên dịch trước mà không cần phải chờ biên dịch mã mỗi khi khởi chạy ứng dụng. Tệp .odex không thực sự cần thiết: Android thực sự có thể chạy trực tiếp mã .dex thông qua việc diễn giải hoặc biên dịch đúng thời điểm (JIT), nhưng tệp .odex cung cấp sự kết hợp tốt nhất giữa tốc độ khởi chạy và tốc độ thời gian chạy nếu có đủ dung lượng.

Ví dụ: Đối với tệp installed-files.txt từ một Nexus 6P chạy Android 7.1 có tổng kích thước hình ảnh hệ thống là 2628MiB (2755792836 byte), bảng chi tiết về những yếu tố đóng góp lớn nhất vào tổng kích thước hình ảnh hệ thống theo loại tệp như sau:

.odex 1391770312 byte 50,5%
.apk 846878259 byte 30,7%
.so (mã C/C++ gốc) 202162479 byte 7,3%
Tệp .oat/hình ảnh .art 163892188 byte 5,9%
Phông chữ 38952361 byte 1,4%
dữ liệu ngôn ngữ icu 27468687 byte 0,9%

Các con số này cũng tương tự đối với các thiết bị khác, vì vậy, trên các thiết bị Nexus/Pixel, tệp .odex chiếm khoảng một nửa phân vùng hệ thống. Điều này có nghĩa là chúng ta có thể tiếp tục sử dụng ext4 nhưng ghi các tệp .odex vào phân vùng B tại nhà máy, sau đó sao chép các tệp đó vào /data trong lần khởi động đầu tiên. Bộ nhớ thực tế được sử dụng với ext4 A/B giống hệt với SquashFS A/B, vì nếu chúng ta đã sử dụng SquashFS, chúng ta sẽ vận chuyển các tệp .odex được chọn trước trên system_a thay vì system_b.

Việc sao chép tệp .odex vào /data có phải là không gian được lưu trên /system sẽ bị mất trên /data không?

Chưa chính xác. Trên Pixel, hầu hết không gian mà các tệp .odex chiếm là dành cho các ứng dụng, thường tồn tại trên /data. Các ứng dụng này nhận bản cập nhật của Google Play, vì vậy, các tệp .apk và .odex trên hình ảnh hệ thống không được sử dụng trong hầu hết thời gian hoạt động của thiết bị. Bạn có thể loại trừ hoàn toàn các tệp đó và thay thế bằng các tệp .odex nhỏ, do hồ sơ điều khiển khi người dùng thực sự sử dụng từng ứng dụng (do đó không cần dung lượng cho các ứng dụng mà người dùng không sử dụng). Để biết thông tin chi tiết, hãy tham khảo bài nói chuyện The Evolution of Art (Sự phát triển của nghệ thuật) tại Google I/O 2016.

Việc so sánh này rất khó khăn vì một số lý do chính sau:

  • Các ứng dụng do Google Play cập nhật luôn có tệp .odex trên /data ngay khi nhận được bản cập nhật đầu tiên.
  • Ứng dụng mà người dùng không chạy hoàn toàn không cần tệp .odex.
  • Quá trình biên dịch dựa trên hồ sơ tạo ra các tệp .odex nhỏ hơn so với quá trình biên dịch trước khi thực thi (vì quá trình trước chỉ tối ưu hoá mã quan trọng về hiệu suất).

Để biết thông tin chi tiết về các tuỳ chọn điều chỉnh dành cho nhà sản xuất thiết bị gốc (OEM), hãy xem phần Định cấu hình ART.

Không có hai bản sao của tệp .odex trên /data phải không?

Việc này phức tạp hơn một chút ... Sau khi hình ảnh hệ thống mới được ghi, phiên bản mới của dex2oat sẽ chạy trên các tệp .dex mới để tạo các tệp .odex mới. Điều này xảy ra trong khi hệ thống cũ vẫn đang chạy, vì vậy, các tệp .odex cũ và mới đều nằm trên /data cùng một lúc.

Mã trong OtaDexoptService (frameworks/base/+/main/services/core/java/com/android/server/pm/OtaDexoptService.java) gọi getAvailableSpace trước khi tối ưu hoá từng gói để tránh tình trạng lấp đầy quá mức /data. Xin lưu ý rằng có sẵn ở đây vẫn là giá trị bảo thủ: đó là dung lượng còn lại trước khi đạt đến ngưỡng dung lượng thấp thông thường của hệ thống (được đo bằng cả tỷ lệ phần trăm và số byte). Vì vậy, nếu /data đã đầy, thì sẽ không có hai bản sao của mỗi tệp .odex. Mã này cũng có BULK_DELETE_THRESHOLD: Nếu thiết bị gần đầy dung lượng trống (như vừa mô tả), các tệp .odex thuộc về các ứng dụng không được sử dụng sẽ bị xoá. Đó là một trường hợp khác không có hai bản sao của mỗi tệp .odex.

Trong trường hợp xấu nhất, khi /data đã đầy, bản cập nhật sẽ chờ cho đến khi thiết bị khởi động lại vào hệ thống mới và không cần đến các tệp .odex của hệ thống cũ nữa. PackageManager xử lý vấn đề này: (frameworks/base/+/main/services/core/java/com/android/server/pm/PackageManagerService.java#7215). Sau khi hệ thống mới khởi động thành công, installd (frameworks/native/+/main/cmds/installd/dexopt.cpp#2422) có thể xoá các tệp .odex mà hệ thống cũ đã sử dụng, đưa thiết bị trở về trạng thái ổn định chỉ có một bản sao.

Vì vậy, mặc dù có thể /data chứa hai bản sao của tất cả tệp .odex, nhưng (a) điều này là tạm thời và (b) chỉ xảy ra nếu bạn có nhiều dung lượng trống trên /data. Ngoại trừ trong quá trình cập nhật, chỉ có một bản sao. Và như một phần của các tính năng tổng thể về độ mạnh mẽ của ART, ART sẽ không bao giờ điền /data bằng các tệp .odex (vì đó cũng sẽ là vấn đề trên hệ thống không phải A/B).

Tất cả các hoạt động ghi/sao chép này có làm tăng mức hao mòn của bộ nhớ flash không?

Chỉ một phần nhỏ của bộ nhớ flash được viết lại: một bản cập nhật hệ thống Pixel đầy đủ sẽ ghi khoảng 2,3GiB. (Ứng dụng cũng được biên dịch lại, nhưng điều này cũng đúng với các ứng dụng không phải A/B.) Theo truyền thống, các OTA đầy đủ dựa trên khối đã ghi một lượng dữ liệu tương tự, vì vậy, tốc độ hao mòn của bộ nhớ flash cũng tương tự.

Việc cài đặt ROM hai phân vùng hệ thống có làm tăng thời gian cài đặt ROM gốc không?

Không. Pixel không tăng kích thước hình ảnh hệ thống (Pixel chỉ chia không gian trên hai phân vùng).

Việc giữ các tệp .odex trên B có làm chậm quá trình khởi động lại sau khi đặt lại dữ liệu về trạng thái ban đầu không?

Có. Nếu bạn đã thực sự sử dụng một thiết bị, tải OTA và đặt lại dữ liệu về trạng thái ban đầu, thì lần khởi động lại đầu tiên sẽ chậm hơn so với bình thường (1 phút 40 giây so với 40 giây trên Pixel XL) vì các tệp .odex sẽ bị mất khỏi B sau OTA đầu tiên và do đó không thể sao chép vào /data. Đó là sự đánh đổi.

Việc đặt lại dữ liệu về trạng thái ban đầu sẽ là một thao tác hiếm khi thực hiện so với việc khởi động thông thường, vì vậy, thời gian thực hiện sẽ ít quan trọng hơn. (Điều này không ảnh hưởng đến người dùng hoặc người đánh giá nhận thiết bị từ nhà máy, vì trong trường hợp đó, phân vùng B sẽ có sẵn.) Việc sử dụng trình biên dịch JIT có nghĩa là chúng ta không cần biên dịch lại mọi thứ, vì vậy, điều này không tệ như bạn nghĩ. Bạn cũng có thể đánh dấu các ứng dụng là yêu cầu biên dịch trước bằng cách sử dụng coreApp="true" trong tệp kê khai: (frameworks/base/+/main/packages/SystemUI/AndroidManifest.xml#23). system_server hiện sử dụng tính năng này vì không được phép JIT vì lý do bảo mật.

Việc lưu trữ các tệp .odex trên /data thay vì /system có làm quá trình khởi động lại sau khi cập nhật qua mạng không dây bị chậm không?

Không. Như đã giải thích ở trên, dex2oat mới được chạy trong khi hình ảnh hệ thống cũ vẫn đang chạy để tạo các tệp mà hệ thống mới cần. Bản cập nhật sẽ không được coi là có sẵn cho đến khi công việc đó hoàn tất.

Chúng tôi có thể (nên) vận chuyển thiết bị A/B 32 GiB không? 16 GiB? 8GiB?

32GiB hoạt động tốt như đã được chứng minh trên Pixel và 320MiB trên 16GiB có nghĩa là giảm 2%. Tương tự, 320MiB trên 8GiB giảm 4%. Rõ ràng là A/B sẽ không phải là lựa chọn được đề xuất trên các thiết bị có 4GiB, vì mức hao tổn 320MiB gần bằng 10% tổng dung lượng có sẵn.

AVB2.0 có yêu cầu OTA A/B không?

Không. Tính năng Khởi động đã xác minh của Android luôn yêu cầu bản cập nhật dựa trên khối, nhưng không nhất thiết phải là bản cập nhật A/B.

OTA A/B có yêu cầu AVB2.0 không?

STT

Bản cập nhật OTA A/B có làm hỏng tính năng bảo vệ khôi phục của AVB2.0 không?

Không. Có một số nhầm lẫn ở đây vì nếu hệ thống A/B không khởi động được vào hình ảnh hệ thống mới, thì hệ thống sẽ tự động quay lại hình ảnh hệ thống "trước đó" (sau một số lần thử lại do trình tải khởi động xác định). Tuy nhiên, điểm chính ở đây là "trước" theo nghĩa A/B thực sự vẫn là hình ảnh hệ thống "hiện tại". Ngay khi thiết bị khởi động thành công một hình ảnh mới, tính năng bảo vệ rollback sẽ kích hoạt và đảm bảo rằng bạn không thể quay lại. Tuy nhiên, cho đến khi bạn khởi động thành công hình ảnh mới, tính năng bảo vệ rollback sẽ không coi đó là hình ảnh hệ thống hiện tại.

Nếu bạn đang cài đặt bản cập nhật trong khi hệ thống đang chạy, thì quá trình đó có chậm không?

Với các bản cập nhật không phải A/B, mục tiêu là cài đặt bản cập nhật nhanh nhất có thể vì người dùng đang chờ và không thể sử dụng thiết bị trong khi bản cập nhật được áp dụng. Với bản cập nhật A/B, điều ngược lại là đúng; vì người dùng vẫn đang sử dụng thiết bị của họ, nên mục tiêu là ít tác động nhất có thể, vì vậy, bản cập nhật được cố tình thực hiện chậm. Thông qua logic trong ứng dụng cập nhật hệ thống Java (đối với Google là GmsCore, gói cốt lõi do GMS cung cấp), Android cũng cố gắng chọn thời điểm người dùng không sử dụng thiết bị. Nền tảng này hỗ trợ việc tạm dừng/tiếp tục cập nhật và ứng dụng có thể sử dụng tính năng đó để tạm dừng cập nhật nếu người dùng bắt đầu sử dụng thiết bị và tiếp tục cập nhật khi thiết bị lại ở trạng thái rảnh.

Có hai giai đoạn khi tải OTA, được hiển thị rõ ràng trong giao diện người dùng là Bước 1/2Bước 2/2 trong thanh tiến trình. Bước 1 tương ứng với việc ghi các khối dữ liệu, còn bước 2 là biên dịch trước các tệp .dex. Hai giai đoạn này khá khác nhau về mức độ tác động đến hiệu suất. Giai đoạn đầu tiên là I/O đơn giản. Điều này đòi hỏi ít tài nguyên (RAM, CPU, I/O) vì nó chỉ sao chép các khối xung quanh một cách chậm rãi.

Giai đoạn thứ hai chạy dex2oat để biên dịch trước hình ảnh hệ thống mới. Rõ ràng là cách này có ít giới hạn hơn về các yêu cầu vì nó biên dịch các ứng dụng thực tế. Và rõ ràng là việc biên dịch một ứng dụng lớn và phức tạp sẽ tốn nhiều công sức hơn so với một ứng dụng nhỏ và đơn giản; trong khi ở giai đoạn 1, không có khối ổ đĩa nào lớn hơn hoặc phức tạp hơn các khối khác.

Quy trình này tương tự như khi Google Play cài đặt bản cập nhật ứng dụng ở chế độ nền trước khi hiển thị thông báo 5 ứng dụng đã cập nhật, như đã thực hiện trong nhiều năm.

Nếu người dùng đang chờ bản cập nhật thì sao?

Cách triển khai hiện tại trong GmsCore không phân biệt giữa bản cập nhật trong nền và bản cập nhật do người dùng khởi tạo, nhưng có thể sẽ phân biệt trong tương lai. Trong trường hợp người dùng yêu cầu cài đặt bản cập nhật một cách rõ ràng hoặc đang xem màn hình tiến trình cập nhật, chúng tôi sẽ ưu tiên công việc cập nhật dựa trên giả định rằng họ đang chủ động chờ quá trình cập nhật hoàn tất.

Điều gì sẽ xảy ra nếu không áp dụng được bản cập nhật?

Với các bản cập nhật không phải A/B, nếu không áp dụng được bản cập nhật, người dùng thường sẽ không sử dụng được thiết bị. Trường hợp ngoại lệ duy nhất là nếu lỗi xảy ra trước khi ứng dụng bắt đầu (ví dụ: do gói không xác minh được). Với bản cập nhật A/B, việc không áp dụng được bản cập nhật sẽ không ảnh hưởng đến hệ thống đang chạy. Bạn chỉ cần thử lại quá trình cập nhật sau.