美文网首页
Android APK缓存

Android APK缓存

作者: ben3726 | 来源:发表于2018-08-27 20:27 被阅读0次

    原文:https://source.android.com/devices/tech/perf/apk-caching

    本文介绍了APK缓存解决方案的设计,以便在支持A/B分区的设备上快速安装预加载的应用程序。

    OEM可以将预加载和流行应用程序放置在APK缓存里,存储在大多数新A/B分区设备上的空B分区中,而不会影响任何面向用户的数据空间。通过在设备上提供APK缓存,新的或最近恢复出厂设置的设备可以立即使用,无需从Google Play下载APK文件。

    用例

    • 将预加载的应用程序存储在B分区中以便更快配置
    • 将流行的应用程序存储在B分区中以便更快恢复

    先决条件

    要使用此功能,设备需要:

    • 安装了Android 8.1(O MR1)版本
    • 实现了A / B分区

    只能在首次启动时复制预加载的内容。这是因为在支持A / B系统更新的设备上,B分区实际上并不存储系统映像文件,而是存储一些预加载内容,如零售演示资源,OAT文件和APK缓存等。将资源复制到/ data分区(这发生在首次启动时)后,B分区将被OTA更新用来下载系统映像的更新版本。

    因此,无法通过OTA更新APK缓存; 它只能在出厂时预装。恢复出厂设置仅影响/ data分区。系统B分区一直保存预加载的内容直到OTA映像被下载。恢复出厂设置后,系统将再次进行首次启动。这意味着如果将OTA映像下载到B分区后,再将设备恢复出厂设置,则APK缓存不可用。

    实现

    方法1. system_other分区上的内容

    赞成:恢复出厂设置后预加载的内容不会丢失(重启后将从B分区复制)。

    反对: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

    1. 编辑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

    1. 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/+/master/sepolicy/preloads_copy.te

    1. 在新/sepolicy/file_contexts 文件中注册域:
    /system/bin/preloads_copy\.sh     u:object_r:preloads_copy_exec:s0
    

    查找示例SELinux上下文文件:device/google/marlin/sepolicy/preloads_copy.te

    1. 在构建时,必须将具有预加载内容的目录复制到 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)
    

    这是一个Makefile中的更改示例,它允许将来自供应商的Git存储库(本例是vendor/google_devices/marlin/preloads)中的APK缓存资源复制到system_other分区上的位置,该位置稍后将被复制到/data/preloads当设备首次启动时。此脚本在构建时运行以准备system_other映像。它希望预加载的内容在vendor/google_devices/marlin/preloads中可用。OEM可以自由选择实际的仓库名称/路径。

    1. APK缓存位于/data/preloads/file_cache并具有以下布局:
    /data/preloads/file_cache/
        app.package.name.1/
              file1
              fileN
        app.package.name.N/
    

    这是设备上的最终目录结构。只要最终文件结构复制上述文件结构,OEM就可以自由选择任何实现方法。

    方法2. 在出厂时存存储用户数据镜像的内容

    此替代方法假定预加载的内容已包含在/data分区的/data/preloads目录中。

    赞成:开箱即用(无需进行设备自定义即可在首次启动时复制文件)。内容已在 /data分区上。

    反对:恢复出厂设置后,预加载的内容会丢失。虽然这对某些人来说可能是可以接受的,但对于在进行质量控制检查后恢复出厂设设备的OEM可能并不总是有效。

    新@SystemApi方法,getPreloadsFileCache()加入到 android.content.Context。它返回预加载缓存中特定于应用程序的目录的绝对路径。

    添加了一个新方法,IPackageManager.deletePreloadsFileCache允许删除preloads目录以回收所有空间。该方法只能由具有SYSTEM_UID的应用程序调用,如“系统服务”或“设置”。

    应用准备

    只有特权应用程序才能访问预加载缓存目录。对于该访问,应用程序必须安装在/system/priv-app目录中。

    验证

    • 首次启动后,设备应在/data/preloads/file_cache目录中包含内容 。
    • 如果设备的存储空间不足,则必须删除file_cache/目录中的内容。

    使用示例ApkCacheTest 应用程序来测试APK缓存。

    1. 通过从根目录运行下面命令来构建应用程序:
    $ make ApkCacheTest
    
    1. 将应用程序安装为特权应用程序。(记住,只有特权应用才能访问APK缓存)。这需要已root的设备:
    $ 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
    
    1. 如果需要,模拟文件缓存目录及其内容(也需要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"
    
    1. 测试应用程序。安装此应用并创建测试file_cache目录后,打开ApkCacheTest应用程序。它应该显示一个test.txt文件及其内容。请参阅此屏幕截图,了解这些结果在用户界面中的显示方式。
    图 1. ApkCacheTest结果

    相关文章

      网友评论

          本文标题:Android APK缓存

          本文链接:https://www.haomeiwen.com/subject/hgktwftx.html