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 渠道包的下载体验,优化用户体验、提高用户留存。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值