Tài liệu này mô tả thiết kế của một giải pháp lưu vào bộ nhớ đệm APK để cài đặt nhanh các ứng dụng được tải sẵn trên một thiết bị hỗ trợ các phân vùng A/B.
Các OEM có thể đặt các ứng dụng tải trước và ứng dụng phổ biến vào bộ nhớ đệm APK được lưu trữ trong phân vùng B hầu như trống trên các thiết bị phân vùng A/B mới mà không ảnh hưởng đến bất kỳ không gian dữ liệu nào mà người dùng nhìn thấy. Nhờ có bộ nhớ đệm APK trên thiết bị, các thiết bị mới hoặc thiết bị vừa được đặt lại về trạng thái ban đầu có thể sử dụng gần như ngay lập tức mà không cần tải tệp APK xuống từ Google Play.
Trường hợp sử dụng
- Lưu trữ các ứng dụng tải sẵn trong phân vùng B để thiết lập nhanh hơn
- Lưu trữ các ứng dụng phổ biến trong phân vùng B để khôi phục nhanh hơn
Điều kiện tiên quyết
Để sử dụng tính năng này, thiết bị cần:
- Đã cài đặt bản phát hành Android 8.1 (O MR1)
- Đã triển khai phân vùng A/B
Bạn chỉ có thể sao chép nội dung được tải sẵn trong lần khởi động đầu tiên. Lý do là vì trên các thiết bị hỗ trợ bản cập nhật hệ thống A/B, phân vùng B không thực sự lưu trữ các tệp hình ảnh hệ thống, mà thay vào đó là nội dung được tải trước như tài nguyên bản trình diễn bán lẻ, tệp OAT và bộ nhớ đệm APK. Sau khi các tài nguyên được sao chép vào phân vùng /data (việc này xảy ra trong lần khởi động đầu tiên), phân vùng B sẽ được các bản cập nhật qua mạng (OTA) dùng để tải các phiên bản mới của ảnh hệ thống xuống.
Do đó, bạn không thể cập nhật bộ nhớ đệm APK thông qua OTA; bạn chỉ có thể tải trước bộ nhớ đệm này tại nhà máy. Thao tác đặt lại về trạng thái ban đầu chỉ ảnh hưởng đến phân vùng /data. Phân vùng B của hệ thống vẫn có nội dung được tải sẵn cho đến khi hình ảnh OTA được tải xuống. Sau khi đặt lại về trạng thái ban đầu, hệ thống sẽ khởi động lại từ đầu. Điều này có nghĩa là tính năng lưu APK vào bộ nhớ đệm sẽ không hoạt động nếu hình ảnh OTA được tải xuống phân vùng B, sau đó thiết bị được đặt lại về trạng thái ban đầu.
Triển khai
Phương pháp 1. Nội dung trên phân vùng system_other
Pro: Nội dung được tải sẵn sẽ không bị mất sau khi bạn đặt lại thiết bị về trạng thái ban đầu. Nội dung này sẽ được sao chép từ phân vùng B sau khi bạn khởi động lại.
Nhược điểm: Cần có dung lượng trên phân vùng B. Quá trình khởi động sau khi khôi phục cài đặt gốc cần thêm thời gian để sao chép nội dung được tải sẵn.
Để sao chép các tệp tải trước trong lần khởi động đầu tiên, hệ thống sẽ gọi một tập lệnh trong /system/bin/preloads_copy.sh
. Tập lệnh được gọi bằng một đối số duy nhất (đường dẫn đến điểm gắn kết chỉ đọc cho phân vùng system_b
):
Để triển khai tính năng này, hãy thực hiện những thay đổi dành riêng cho thiết bị này. Sau đây là một ví dụ của Marlin:
- Thêm tập lệnh thực hiện thao tác sao chép vào tệp
device-common.mk
(trong trường hợp này làdevice/google/marlin/device-common.mk
), như sau: Tìm nguồn tập lệnh mẫu tại: device/google/marlin/preloads_copy.sh# Script that copies preloads directory from system_other to data partition PRODUCT_COPY_FILES += \ device/google/marlin/preloads_copy.sh:system/bin/preloads_copy.sh
- Chỉnh sửa tệp
init.common.rc
để tệp này tạo thư mục/data/preloads
và thư mục con cần thiết: Tìm nguồn tệpmkdir /data/preloads 0775 system system
mkdir /data/preloads/media 0775 system system
mkdir /data/preloads/demo 0775 system system
init
ví dụ tại: device/google/marlin/init.common.rc - Xác định một miền SELinux mới trong tệp
preloads_copy.te
: Tìm một tệp miền SELinux mẫu tại: /device/google/marlin/+/android16-release/sepolicy/preloads_copy.tetype preloads_copy, domain, coredomain; type preloads_copy_exec, exec_type, vendor_file_type, file_type; init_daemon_domain(preloads_copy) allow preloads_copy shell_exec:file rx_file_perms; allow preloads_copy toolbox_exec:file rx_file_perms; allow preloads_copy preloads_data_file:dir create_dir_perms; allow preloads_copy preloads_data_file:file create_file_perms; allow preloads_copy preloads_media_file:dir create_dir_perms; allow preloads_copy preloads_media_file:file create_file_perms; # Allow to copy from /postinstall allow preloads_copy system_file:dir r_dir_perms;
- Đăng ký miền trong một tệp
mới:/sepolicy/file_contexts Tìm một tệp ngữ cảnh SELinux mẫu tại: device/google/marlin/sepolicy/preloads_copy.te/system/bin/preloads_copy\.sh u:object_r:preloads_copy_exec:s0
- Tại thời điểm tạo, thư mục có nội dung tải sẵn phải được sao chép vào phân vùng
system_other
: Đây là ví dụ về một thay đổi trong Makefile cho phép sao chép các tài nguyên bộ nhớ đệm APK từ kho lưu trữ Git của nhà cung cấp (trong trường hợp này là vendor/google_devices/marlin/preloads) đến vị trí trên phân vùng system_other. Sau đó, vị trí này sẽ được sao chép vào /data/preloads khi thiết bị khởi động lần đầu tiên. Tập lệnh này chạy trong thời gian xây dựng để chuẩn bị hình ảnh system_other. Thư mục này chứa nội dung được tải sẵn trong vendor/google_devices/marlin/preloads. OEM có thể tự do chọn tên/đường dẫn thực tế của kho lưu trữ.# Copy contents of preloads directory to system_other partition PRODUCT_COPY_FILES += \ $(call find-copy-subdir-files,*,vendor/google_devices/marlin/preloads,system_other/preloads)
- Bộ nhớ đệm APK nằm trong
/data/preloads/file_cache
và có bố cục sau: Đây là cấu trúc thư mục cuối cùng trên các thiết bị. Các OEM có thể tự do chọn bất kỳ phương pháp triển khai nào miễn là cấu trúc tệp cuối cùng sao chép cấu trúc được mô tả ở trên./data/preloads/file_cache/ app.package.name.1/ file1 fileN app.package.name.N/
Phương pháp 2. Nội dung trên hình ảnh dữ liệu người dùng được ghi vào bộ nhớ flash tại nhà máy
Phương pháp thay thế này giả định rằng nội dung được tải sẵn đã có trong thư mục /data/preloads
trên phân vùng /data
.
Ưu điểm: Hoạt động ngay khi xuất xưởng – không cần tuỳ chỉnh thiết bị để sao chép tệp khi khởi động lần đầu. Nội dung đã có trên phân vùng /data
.
Nhược điểm: Nội dung được tải sẵn sẽ bị mất sau khi bạn đặt lại về trạng thái ban đầu. Mặc dù điều này có thể chấp nhận được đối với một số người, nhưng không phải lúc nào cũng phù hợp với các OEM đặt lại thiết bị về trạng thái ban đầu sau khi kiểm tra chất lượng.
Một phương thức @SystemApi mới, getPreloadsFileCache()
, đã được thêm vào android.content.Context
. Phương thức này trả về đường dẫn tuyệt đối đến một thư mục dành riêng cho ứng dụng trong bộ nhớ đệm được tải sẵn.
Đã thêm một phương thức mới là IPackageManager.deletePreloadsFileCache
. Phương thức này cho phép xoá thư mục tải trước để giải phóng toàn bộ dung lượng. Chỉ những ứng dụng có SYSTEM_UID mới có thể gọi phương thức này, tức là máy chủ hệ thống hoặc phần Cài đặt.
Chuẩn bị ứng dụng
Chỉ những ứng dụng có đặc quyền mới có thể truy cập vào thư mục bộ nhớ đệm tải trước. Để có quyền truy cập đó, bạn phải cài đặt các ứng dụng trong thư mục /system/priv-app
.
Xác nhận kết quả
- Sau lần khởi động đầu tiên, thiết bị phải có nội dung trong thư mục
/data/preloads/file_cache
. - Bạn phải xoá nội dung trong thư mục
file_cache/
nếu thiết bị sắp hết bộ nhớ.
Sử dụng ứng dụng ví dụ ApkCacheTest để kiểm thử bộ nhớ đệm APK.
- Tạo ứng dụng bằng cách chạy lệnh này từ thư mục gốc:
make ApkCacheTest
- Cài đặt ứng dụng dưới dạng một ứng dụng đặc quyền. (Hãy nhớ rằng chỉ các ứng dụng đặc quyền mới có thể truy cập vào bộ nhớ đệm APK.)
Việc này yêu cầu thiết bị bị can thiệp hệ thống:
adb root && adb remount
adb shell mkdir /system/priv-app/ApkCacheTest
adb push $ANDROID_PRODUCT_OUT/data/app/ApkCacheTest/ApkCacheTest.apk /system/priv-app/ApkCacheTest/
adb shell stop && adb shell start
- Mô phỏng thư mục lưu vào bộ nhớ đệm của tệp và nội dung của thư mục đó nếu cần (cũng yêu cầu đặc quyền truy cập gốc):
adb shell mkdir -p /data/preloads/file_cache/com.android.apkcachetest
adb shell restorecon -r /data/preloads
adb shell "echo "Test File" > /data/preloads/file_cache/com.android.apkcachetest/test.txt"
- Kiểm thử ứng dụng. Sau khi cài đặt ứng dụng và tạo thư mục kiểm thử
file_cache
, hãy mở ứng dụng ApkCacheTest. Ứng dụng này sẽ cho thấy một tệptest.txt
và nội dung của tệp đó. Hãy xem ảnh chụp màn hình này để biết cách các kết quả này xuất hiện trong giao diện người dùng.
Hình 1. Kết quả ApkCacheTest.