EdgeOne 边缘函数 - 如何实现边缘 APK 多渠道动态打包

本文介绍如何使用 EdgeOne 边缘函数,在边缘节点上将渠道信息注入到 APK 包中,实现边缘 APK 多渠道动态打包。

阅读本文之前,请先了解以下背景知识:
1. APK 签名原理(V1 & V2)
2. APK 多渠道包构建实现原理
3. EdgeOne 边缘函数

EdgeOne 边缘 APK 多渠道动态打包方案 与传统的 VasDollyWalle、 ApkTool 以及 Android Gradle Plugin 方案的对比:

相比传统方案,边缘 APK 多渠道动态打包方案具备一站式动态打包与加速的能力,减小 APK 渠道包的维护难度降低接入成本满足业务多维度的诉求

一、前言

在传统的 APK 多渠道打包方案中,开发者需要针对不同的渠道构建对应版本的 APK 包,这样导致 APK 渠道包数量多,难以维护。

同时,在使用 CDN 对 APK 进行下载加速时,每一个 APK 渠道包都需要各自缓存,因此会出现加速效果不均匀的问题。

本文使用 EdgeOne 边缘函数实现 边缘 APK 多渠道动态打包方案(本文简称 APK 动态打包),只需要一份 APK 包,根据下载渠道的不同,在下载时动态的注入渠道信息。同时,由于只存在一份 APK 包,也解决了 CDN 加速不均匀的问题。

二、方案设计 - APK 动态打包

APK 动态打包方案 有几个关键条件:

  1. APK 包必须经过处理:无论采用何种方式,只要我们向 APK 包中注入信息,就会改变其原始数据。因此,我们需要确保处理后的 APK 仍然是一个合法的文件;

  2. 避免在处理 APK 包时注入渠道信息:我们需要将注入渠道信息的操作后移到下载流程,这样才能保证只有一份被处理过的 APK 包;

  3. 在下载 APK 包时注入渠道信息:我们需要将 "注入渠道信息" 和 "下载" 这两个操作绑定在一起。当下载操作实际发生时,将渠道信息动态地注入到 APK 包的适当位置;

如上所述,我们通过将 处理 APK 包 和 渠道信息注入 解耦,实现 动态 打包的能力,整个方案流程如图所示:

如上图所示,整个方案中存在两个关键步骤,下面分别看下每个关键步骤中,需要进行哪些操作。

2.1 APK 预处理

APK 包需要进行预处理,注入空白数据,并标记好空白数据所在位置,这样既保证了 APK 合法,又避免了过早注入专有的渠道信息。

APK 预处理流程 与 传统的多渠道构建流程 高度相似,只是将原来需要注入的 渠道信息 更换为 空白数据

对于 V1 签名的 APK 包:

  1. 生成一块长度为 512 的空白数据;

  2. 找到 EOCD 的注释区的启始位置;

  3. 将空白数据追加到注释区,并更新注释长度;

  4. 标记空白数据起始位置;

示意图如下:

对于 V2 签名的 APK 包:

  1. 生成一段长度为 10240 的空白数据;

  2. 包装成符合 APK Signing Block 标准的 id-value Pair;

  3. 将 id-value Pair 存入 APK Signing Block 中;

  4. 更新 EOCD 中的相关数据(各种偏移量);

  5. 标记出空白数据对应的 id-value Pair 的所在位置;

示意图如下:

2.2 渠道信息动态注入

我们使用 EdgeOne 边缘函数在边缘节点进行以下操作:

  1. 在 HTTP 请求中获取 渠道信息;

  2. 找到 预处理后的 APK 包中的空白数据位置;

  3. 将渠道信息替换到空白数据中;

  4. 携带已经注入渠道信息的 APK 包响应客户端;

EgdeOne 边缘函数运行在边缘节点的 Serverless 环境中,更加贴近用户,配合 EdgeOne 缓存,可以更加快速的响应客户端。

三、方案实现 - APK 动态打包

3.1 APK 预处理

使用 COS + SCF 的方案来实现 APK 包的预处理过程,具体步骤为:

  1. 上传原始 APK 包至 COS 存储桶;

  2. APK 包上传触发 SCF Event 函数执行:

    • 获取原始 APK 包;

    • 处理 APK 包,注入空白数据;

    • 将处理好的 APK 包回传至客户 COS 存储桶,并将空白数据偏移量写入 response header 中;

详细流程如图所示:

SCF 相关代码目前不做开放,可以直接在 SCF 模版市场选择 EdgeOne APK 动态打包模版 使用。

3.2 渠道信息动态注入

使用 EdgeOne 边缘函数实现渠道信息的动态注入,具体步骤为:

  1. 客户端请求 APK 文件,假定请求 URL 为 https://test.com/handle.apk?comment=test

  2. 请求触发边缘函数执行:

    • 获取 request query 参数中的 comment 值;

    • fetch 请求 handle.apk 文件,获取 APK 包数据和 response header 中的 offset 信息;

    • 将 comment 信息写入 APK 包的 offset 位置;

    • 已经注入 comment 信息的 APK 包响应客户端;

详细流程如图所示:

边缘函数代码放在附件中。
实际函数代码中,有分片处理和流式响应相关优化,保证关键步骤的清晰,文章中没有体现。

四、部署上线 - APK 动态打包

目前,我们已经整合 COS、SCF、EdgeOne 三大产品的能力,将几个关键步骤的实现封装。只需要简单配置,就可以搭建起 APK 动态打包的工作流。

步骤1: 创建 COS 存储桶

在 COS 对象存储 中创建用于上传 APK 母包的目录(不要直接在根目录上传,建议 APK 母包上传文件夹和 APK 预处理包存储文件夹一一对应):

步骤2: 创建 SCF 云函数

为了方便使用,用于 APK 预处理的 SCF 云函数代码已经作为模版上线 SCF 模版市场。

在 云函数 SCF 通过 EdgeOne APK 动态打包的模板新建函数:

待填写信息如下:

环境变量

  • outputPath:自定义云函数 SCF 处理 APK 母包后输出到 COS 存储桶的目录,如:/v2-vasdolly_output

  • packVersion:指定签名格式,取值:v1v2-VasDollyv2-Wallev2-Custom

  • blockId(可选):当 packVersion 设置为 v2-Custom 时,需要指定 blockId

关于 packVersion 的取值,参照下表:

APK 签名版本packVersion 取值
V1v1
V2v2-VasDolly : 将渠道信息保存在 id 为 0x881155ff (VasDolly 默认)的 id-value 对;
v2-Walle:将渠道信息保存在 id 为 0x71777777 (Walle 默认)的 id-value 对;
v2-Custom:将渠道信息保存在 id 为 blockId (由 blockId 环境变量指定)的 id-value 对;

运行角色

可选择 SCF_ExecuteRole 或新建角色,确保有 COS 存储桶的读写权限:

文件系统(可选)

如果 APK 母包大于 200M,需挂载 CFS 云硬盘,如下所示:

由于 SCF 侧的限制,每个云函数在执行过程中,拥有一块 500MB 的临时磁盘空间。

处理 APK 文件时,磁盘中同时存在原始 APK 文件和处理后的 APK 文件,因此处理过大的 APK 文件,需要挂在额外的文件存储系统,详情请参见  挂载 CFS 文件系统 。

触发管理

  • 触发方式:选择 COS 触发 COS Bucket,选择该可用区下母包所在的 COS 存储桶;

  • 事件类型:选择全部创建;

  • 前缀过滤:请输入母包上传的目录,如您的母包在 test 目录下,即填写 test/

  • 后缀过滤:请输入 .apk

借助 COS 和 SCF 的联动能力,APK 预处理 流程已经可以顺畅的运行起来了,在 COS 的指定目录下上传 APK 母包,经过云函数处理,在对应的 output 文件夹下可获取到云函数 SCF 处理后新的 APK 包,如下所示:

点击【详情】,在自定义 Headers 部分可查看到云函数返回的自定义 Headers:

步骤3: 创建 EdgeOne 边缘函数

通过 1、2 步的配置,我们顺利打通了 APK 预处理 的工作流程;接下来,我们需要借助 EdgeOne 边缘函数的能力,在边缘 Serverless 运行环境中,使用 JavaScript 代码实现 渠道信息动态注入

使用 EdgeOne 边缘函数前,需要先将自己的域名接入到 EdgeOne,同时,源站配置为 APK 母包所在的存储桶:

加速域名同站点下创建边缘函数:

将附件中的边缘函数代码粘贴到代码区域,并创建函数。

内部用户还可以使用  边缘函数脚手架 TEF CLI 创建、调试、部署边缘函数代码

步骤4: 配置触发规则

部署函数后配置触发规则,其 HOST 值为之前创建的加速域名,如下所示:

步骤5: 验证效果

在浏览器中输入 URL?comment=xxxx 即可触发边缘函数,动态地将渠道信息注入到指定位置。

以 v2-VasDolly 方式为例,我们可以使用 VasDolly 工具来读取动态注入的渠道信息:

五、总结

EdgeOne 边缘函数拥有 分布式部署贴近用户超低延迟弹性扩容Serverless 环境 等优势,借助 EdgeOne 边缘函数,我们成功实现了边缘 APK 多渠道动态打包方案。

APK 动态打包工作流打通后,开发者无需再关注其他操作,只需要简单两步,即可实现多渠道包的构建,降低了 APK 渠道包的维护、使用难度。

同时,业务源站(COS)只需存放一个 APK 预处理包,解决了大量 APK 渠道包托管问题,降低了业务成本。

更重要的是,边缘 APK 多渠道动态打包方案借助边缘函数独特的建构优势,配合 EdgeOne 缓存,优化了 APK 渠道包的下载体验,优化用户体验、提高用户留存。

  • 25
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值