本文說明 APK 快取解決方案的設計,可在支援 A/B 分區的裝置上快速安裝預先載入的應用程式。
原始設備製造商 (OEM) 可以在新款A/B 分割裝置的空白 B 分割區中儲存 APK 快取,並在其中放置預先載入內容和熱門應用程式,不會影響任何面向使用者的資料空間。只要在裝置上提供 APK 快取,新裝置或最近恢復原廠設定的裝置就能立即使用,無須從 Google Play 下載 APK 檔案。
用途
- 將預先載入的應用程式儲存在 B 分割區,加快設定速度
- 將熱門應用程式儲存在 B 分區,加快還原速度
必要條件
如要使用這項功能,裝置必須符合以下條件:
- 已安裝 Android 8.1 (O MR1) 版本
- 已實作 A/B 分區
預先載入的內容只能在首次啟動時複製。這是因為在支援 A/B 系統更新的裝置上,B 分區實際上並未儲存系統映像檔,而是預先載入零售示範資源、OAT 檔案和 APK 快取等內容。資源複製到 /data 分區後 (這會在首次開機時發生),無線 (OTA) 更新會使用 B 分區下載更新版的系統映像檔。
因此,APK 快取無法透過 OTA 更新,只能在工廠預先載入。工廠重置只會影響 /data 分割區。在 OTA 映像檔下載之前,系統 B 分區仍會保留預先載入的內容。恢復原廠設定後,系統會再次進行首次啟動。也就是說,如果 OTA 映像檔下載至 B 分區,然後裝置恢復原廠設定,則無法使用 APK 快取功能。
實作
方法 1. system_other 分割區的內容
Pro:恢復原廠設定後,預先載入的內容不會遺失,系統會在重新啟動後從 B 分區複製這些內容。
Con:需要 B 分區的空間。恢復原廠設定後的開機作業需要額外的時間來複製預先載入的內容。
為了在首次開機時複製預先載入內容,系統會在 /system/bin/preloads_copy.sh
中呼叫指令碼。系統會使用單一引數 (system_b
分割區的唯讀掛載點路徑) 呼叫指令碼:
如要實作這項功能,請進行下列裝置專屬變更。以下是 Marlin 的範例:
- 將執行複製作業的指令碼新增至
device-common.mk
檔案 (在本例中為device/google/marlin/device-common.mk
),如下所示: 請參閱以下指令碼來源: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
- 編輯
init.common.rc
檔案,讓檔案建立必要的/data/preloads
目錄和子目錄: 如需mkdir /data/preloads 0775 system system
mkdir /data/preloads/media 0775 system system
mkdir /data/preloads/demo 0775 system system
init
檔案來源範例,請參閱:device/google/marlin/init.common.rc - 在
preloads_copy.te
檔案中定義新的 SELinux 網域: 請前往以下位置查看 SELinux 網域檔案範例:/device/google/marlin/+/main/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;
- 在新的
檔案中註冊網域:/sepolicy/file_contexts 請前往以下位置查看 SELinux 情境檔案範例:device/google/marlin/sepolicy/preloads_copy.te/system/bin/preloads_copy\.sh u:object_r:preloads_copy_exec:s0
- 在建構期間,含有預先載入內容的目錄必須複製到
system_other
分割區: 這是 Makefile 變更的範例,可從供應商的 Git 存放區 (在本例中為 vendor/google_devices/marlin/preloads) 複製 APK 快取資源,並將其複製至 system_other 分割區的某個位置,該位置會在裝置首次開機時複製至 /data/preloads。這個指令碼會在建構期間執行,以準備 system_other 映像檔。系統會預期預先載入的內容會在 vendor/google_devices/marlin/preloads 中提供。OEM 可以自由選擇實際的存放區名稱/路徑。# 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)
- APK 快取位於
/data/preloads/file_cache
中,並具有下列版面配置: 這是裝置上的最終目錄結構。OEM 可以自由選擇任何導入方法,只要最終檔案結構複製上述結構即可。/data/preloads/file_cache/ app.package.name.1/ file1 fileN app.package.name.N/
方法 2. 工廠刷入的使用者資料圖片內容
這個替代方法假設預先載入的內容已包含在 /data
分區的 /data/preloads
目錄中。
優點:開箱即用,無須進行裝置自訂設定,即可在首次啟動時複製檔案。內容已位於 /data
區段。
缺點:恢復原廠設定後,預先載入的內容會遺失。雖然這對部分人來說可能可接受,但對於在品質管制檢查後將裝置重設為原廠設定的 OEM 廠商來說,這可能不一定可行。
android.content.Context
新增了新的 @SystemApi 方法 getPreloadsFileCache()
。它會傳回預先載入快取中應用程式專屬目錄的絕對路徑。
我們新增了 IPackageManager.deletePreloadsFileCache
方法,可刪除預先載入目錄,以便回收所有空間。只有具有 SYSTEM_UID 的應用程式 (例如系統伺服器或設定) 才能呼叫此方法。
應用程式準備
只有具備權限的應用程式才能存取預先載入快取目錄。應用程式必須安裝在 /system/priv-app
目錄中,才能取得該存取權。
驗證
- 裝置首次啟動後,
/data/preloads/file_cache
目錄中應會出現內容。 - 如果裝置的儲存空間不足,必須刪除
file_cache/
目錄中的內容。
使用範例 ApkCacheTest 應用程式測試 APK 快取。
- 在根目錄中執行下列指令,建構應用程式:
make ApkCacheTest
- 以具有特殊權限的應用程式身分安裝應用程式 (請注意,只有具有特殊權限的應用程式才能存取 APK 快取)。這項作業需要使用已解鎖的裝置:
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
- 模擬檔案快取目錄及其內容 (也需要 Root 權限):
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"
- 測試應用程式。安裝應用程式並建立測試
file_cache
目錄後,請開啟 ApkCacheTest 應用程式。應用程式應會顯示一個檔案test.txt
及其內容。請參閱這張螢幕截圖,瞭解這些結果在使用者介面中的顯示方式。
圖 1. ApkCacheTest 結果。