APK 快取

本文件說明如何設計可快速安裝的 APK 快取解決方案 裝置的預先載入應用程式數量。

原始設備製造商 (OEM) 可將預先載入和熱門應用程式,存放在大部分儲存在 在以 A/B 分區的新裝置上,只有空白 B 分區,而不影響 用於面向使用者的資料空間在新的或 近期恢復原廠設定的裝置幾乎就能立即使用, 不必從 Google Play 下載 APK 檔案。

用途

  • 將預先載入的應用程式儲存在 B 分區中,加快設定速度
  • 將熱門應用程式儲存在 B 分區中,加快還原速度

必要條件

如要使用這項功能,裝置必須符合下列條件:

  • 已安裝 Android 8.1 (O MR1) 版本
  • 已導入 A/B 分區

預先載入的內容只能在首次啟動時複製。這是因為 支援 A/B 系統更新的裝置中,B 分區實際上並未儲存 系統映像檔檔案 而是預先載入零售商展示資源 OAT 檔案和 APK 快取。將資源複製到 /data 後 (在第一次啟動時執行),無線 (OTA) 將使用 B 分區 更新

因此無法透過 OTA 更新 APK 快取。且只能預先載入 因為我們 在工廠工作人員恢復原廠設定只會影響 /data 分區。系統 B 在下載 OTA 映像檔之前,分區仍會預先載入內容。 恢復原廠設定後,系統會再次執行首次啟動程序,也就是 APK 如果 OTA 映像檔下載到 B 分區,就無法使用快取。 ,裝置就會恢復原廠設定

實作

方法 1.內容已開啟 system_other 分區

Pro:恢復原廠設定後不會遺失預先載入的內容 - 重新啟動後即可從 B 分區複製。

Con:需要 B 分區的空間。恢復原廠設定後啟動 需要更多時間來複製預先載入的內容。

為了在初次啟動時複製預先載入,系統會呼叫指令碼。 在「/system/bin/preloads_copy.sh」中。系統會使用單個 引數 (system_b 唯讀掛接點的路徑 分區):

如要實作這項功能,請對裝置執行特定變更。以下是 Marlin 的其中一個範例

  1. 新增執行複製作業的指令碼至 device-common.mk 檔案 (在本例中為 device/google/marlin/device-common.mk),如下所示:
    # 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
    
    指令碼來源範例:device/google/marlin/preloads_copy.sh
  2. 編輯 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
  3. preloads_copy.te 檔案中定義新的 SELinux 網域:
    type 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;
    
    如需 SELinux 網域檔案範例,請前往:/device/google/marlin/+/main/sepolicy/preloads_copy.te
  4. 在新的「/sepolicy/file_contexts」中註冊網域 檔案:
    /system/bin/preloads_copy\.sh     u:object_r:preloads_copy_exec:s0
    
    如需 SELinux 結構定義檔案範例,請前往:device/google/marlin/sepolicy/preloads_copy.te
  5. 在建構期間,必須將含有預先載入內容的目錄複製到 system_other 個分區:
    # 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 快取的 Makefile 變更範例 來自供應商 Git 存放區的資源 (在本例中是 provider/google_devices/marlin/preloads) 到 system_other 分區的位置 系統稍後會在裝置首次啟動時複製 /data/preloads 讓應用程式從可以最快做出回應的位置 回應使用者要求這個指令碼會在建構期間執行,準備 system_other 映像檔。符合預期 供應商/google_devices/marlin/preloads 中皆會提供預先載入的內容。OEM 您可以自行選擇實際的存放區名稱/路徑
  6. APK 快取位於 /data/preloads/file_cache,且 如下版面配置:
    /data/preloads/file_cache/
        app.package.name.1/
              file1
              fileN
        app.package.name.N/
    
    這是裝置上的最終目錄結構。原始設備製造商 (OEM) 可自由挑選 任何實作方法,只要最終的檔案結構複製了 上述任一資源

方法 2.使用者資料內容 映像檔在原廠更新時刷新

這個替代方法假設預先載入的內容已包含在 /data 分區上的 /data/preloads 目錄。

Pro:立即可用,無須製作裝置 ,並在首次啟動時複製檔案。內容已經位於 /data 個分區。

缺點:恢復原廠設定後,預先載入的內容會遺失。雖然 對某些人來說,這是可以接受的,但生產的原始設備製造商 (OEM) 不一定能使用此策略 並在進行品質驗證 (QC) 檢查後重設裝置。

已將新的 @SystemApi 方法 getPreloadsFileCache() 新增至 android.content.Context。該元件會傳回指向 特定的應用程式目錄

已新增方法「IPackageManager.deletePreloadsFileCache」 ,允許刪除預先載入目錄來收回所有空間。這個方法 只能由含有 SYSTEM_UID 的應用程式 (也就是系統伺服器或「設定」) 呼叫。

應用程式準備工作

只有特殊權限的應用程式才能存取預先載入快取目錄。為此 存取權,應用程式必須安裝在 /system/priv-app 目錄中。

驗證

  • 初次啟動後,裝置中應該會有 /data/preloads/file_cache 目錄內。
  • 如果 file_cache/ 裝置的儲存空間不足。

使用範例 ApkCacheTest ,用於測試 APK 快取。

  1. 從根目錄執行下列指令,建構應用程式:
    make ApkCacheTest
    
  2. 將應用程式安裝為具有特殊權限的應用程式。(提醒您,只有具有特殊權限的應用程式才能存取 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
    
  3. 視需要模擬檔案快取目錄及其內容 (也需要 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"
    
  4. 測試應用程式。安裝應用程式並建立測試 file_cache 目錄後,請開啟 ApkCacheTest 應用程式。畫面上應該會顯示一個檔案 test.txt 及其內容。請參閱這個螢幕截圖,瞭解這些結果在使用者介面中的顯示方式。

    圖 1. ApkCacheTest 結果。