本文我将给大家介绍一个 apk 打包工具 VasDolly 的使用介绍、原理以及如何在服务端接入 VasDolly 进行服务端打渠道包操作。

使用介绍

VasDolly 是一个快速多渠道打包工具,同时支持基于 V1 和 V2 签名进行多渠道打包。插件本身会自动检测 Apk 使用的签名类别,并选择合适的多渠道打包方式,对使用者来说完全透明。

项目地址:https://github.com/Tencent/VasDolly

项目构建方式:gradle

VasDolly 官方对于 VasDolly 的定位是安卓端多渠道打包工具,由安卓开发接入安卓项目中使用。VasDolly 官方还提供了 jar 包工具通过命令行方式进行打包操作。

在安卓项目中要使用 VasDolly,你需要先在你的项目中添加对 VasDolly 插件和 helper 类库的依赖。具体步骤如下:

  • 在根工程的 build.gradle 中,添加对打包插件的依赖:
dependencies {
classpath 'com.android.tools.build:gradle:7.0.3'classpath 'com.tencent.vasdolly:plugin:3.0.6'
}
  • 在主 App 工程的 build.gradle 中,添加对 VasDolly 插件的引用:
apply plugin: 'com.tencent.vasdolly'
  • 在主 App 工程的 build.gradle 中,添加读取渠道信息的 helper 类库依赖:
dependencies {
api 'com.tencent.vasdolly:helper:3.0.6'
}
  • 配置渠道列表。你可以通过两种方式配置渠道列表,一种是在 gradle.properties 文件中指定渠道文件名称,该渠道文件必须位于根工程目录下,一行一个渠道信息。例如:
channel_file=channel.txt

其中 channel.txt 文件内容如下:

yingyongbao
gamecenter
xiaomi
huawei
oppo
vivo

另一种方式是在 channel 或者 rebuildChannel 属性中通过 channelFile 属性指定渠道文件,一行一个渠道信息。例如:

channel {
//指定渠道文件
channelFile = file("/Users/leon/Downloads/testChannel.txt")
}
  • 通过 Gradle 生成多渠道包。你可以选择直接编译生成多渠道包,或者根据已有基础包重新生成多渠道包。

    如果你选择直接编译生成多渠道包,你需要配置渠道文件、渠道包的输出目录和渠道包的命名规则。例如:
channel {
//指定渠道文件
channelFile = file("/Users/leon/Downloads/testChannel.txt")
//多渠道包的输出目录,默认为new File (project.buildDir,"channel")
outputDir = new File(project.buildDir,"xxx")
//多渠道包的命名规则,默认为:$ {appName}-$ {versionName}-$ {versionCode}-$ {flavorName}-$ {buildType}-$ {buildTime}
apkNameFormat ='$ {appName}-$ {versionName}-$ {versionCode}-$ {flavorName}-$ {buildType}'//快速模式:生成渠道包时不进行校验(速度可以提升10倍以上,默认为false)
fastMode = false//buildTime的时间格式,默认格式:yyyyMMdd-HHmmss
buildTimeDateFormat = 'yyyyMMdd-HH:mm:ss'//低内存模式(仅针对V2签名,默认为false):只把签名块、中央目录和EOCD读取到内存,不把最大头的内容块读取到内存,在手机上合成APK时,可以使用该模式
lowMemory = false
}

然后,通过 gradle channelDebug 或 gradle channelRelease 命令分别生成 Debug 和 Release 的多渠道包。

如果你选择根据已有基础包重新生成多渠道包,你需要配置渠道文件、基础包的路径和渠道包的输出目录。例如:

rebuildChannel {
//指定渠道文件
channelFile = file("/Users/leon/Downloads/testReChannel.txt")
// 已有APK文件地址(必填),如new File (project.rootDir, "/baseApk/app_base.apk"),文件名中的base将被替换为渠道名
baseApk = new File (project.rootDir, "/baseApk/app_base.apk")
//默认为new File (project.buildDir, "rebuildChannel")
outputDir = new File(project.buildDir,"yyy")
//快速模式:生成渠道包时不进行校验(速度可以提升10倍以上,默认为false)
fastMode = false//低内存模式(仅针对V2签名,默认为false):只把签名块、中央目录和EOCD读取到内存,不把最大头的内容块读取到内存,在手机上合成APK时,可以使用该模式
lowMemory = false
}

然后,通过 gradle rebuildChannel 命令生成多渠道包。

原理

VasDolly 实现原理官方讲解地址:https://github.com/Tencent/VasDolly/wiki/VasDolly实现原理

VasDolly 的原理是利用 APK 文件的特殊结构,将渠道信息写入到 APK 文件的空白区域,从而实现无损的多渠道打包。具体来说,VasDolly 根据 APK 文件使用的签名类别,选择不同的多渠道打包方式。

如果 APK 文件使用的是 V1 签名,那么 VasDolly 会将渠道信息写入到 APK 文件的 Zip Comment 区域。Zip Comment 是 Zip 文件格式中的一个字段,用于存储一些注释信息,通常不会被解压缩工具或者系统解析。因此,将渠道信息写入到 Zip Comment 区域,不会影响 APK 文件的完整性和安全性。同时,由于 Zip Comment 区域位于 APK 文件的末尾,所以写入渠道信息的速度非常快,只需要修改一个字节的偏移量即可。

如果 APK 文件使用的是 V2 或者 V3 签名,那么 VasDolly 会将渠道信息写入到 APK Signing Block 区域。APK Signing Block 是 V2 或者 V3 签名引入的一个新区域,用于存储签名相关的数据。每个数据都有一个 ID 来标识其类型,例如 0x7109871a 表示 V2 签名数据。VasDolly 会使用一个自定义的 ID(0x71777777)来标识渠道信息,并将其写入到 APK Signing Block 区域。由于这个区域不会被系统解析,所以不会影响 APK 文件的安全性。同时,由于这个区域位于中央目录和 EOCD 之前,所以写入渠道信息的速度也很快,只需要修改两个字节的偏移量即可。

通过这种方式,VasDolly 可以实现在不重新签名和对齐的情况下,快速生成多个渠道包。在应用运行时,可以通过 VasDolly 提供的 helper 类库来读取渠道信息,并进行相应的处理。

服务端接入 VasDolly 教程

安卓接入了 VasDolly 之后,就该我们服务端出手了,服务端如果能实现渠道打包的操作,运营每次上新渠道就不需要再找安卓进行新渠道打包,运营直接在后台上传母包,选定渠道后即可获取对应的渠道包,可以节约大家的时间,避免耗费人力在渠道打包这一步。由此可见,服务端进行渠道打包操作还是有必要的。

意外发现

一开始我是想用官方提供的 jar 包工具,通过命令行调用的方式来实现服务端打渠道包的,官方提供的 readme 文档如下,

但是由于博主项目是使用容器环境部署,要是用命令行打包的话,需要引入 VasDolly jar 包并且挂载都容器中,感觉比较麻烦。就想能不能直接引入 VasDolly 依赖来实现打包操作。

于是我在 maven 中央仓库搜索了 com.tencent.vasdolly 关键字后,有了如下发现,

可以看到 VasDolly 虽然是一个 Gradle 项目,但是官方也提供了部分模块的在 Maven 中的 pom 坐标。

查看 VasDolly 仓库代码,发现官方定义了 write 模块,

进入其中,发现了 readme 内容如下,

Ok,到这里,我们发现其实官方提供了 pom 依赖接入,直接使用 ChannelWriter 即可实现渠道打包的操作。

具体教程

  • 在后端 maven 项目中引入 VasDolly 的 pom 依赖,当前最新依赖版本如下,
  <dependency>
<groupId>com.tencent.vasdolly</groupId>
<artifactId>writer</artifactId>
<version>3.0.6</version>
</dependency>
<dependency>
<groupId>com.tencent.vasdolly</groupId>
<artifactId>common</artifactId>
<version>3.0.6</version>
</dependency>
<dependency>
<groupId>com.tencent.vasdolly</groupId>
<artifactId>reader</artifactId>
<version>3.0.6</version>
</dependency>
  • 然后我们就可以利用 ChannelWriter 类实现渠道打包操作,ChannelWriter 类提供的 V2 签名打渠道包方法如下:
  public static void addChannelByV2(File apkFile, String channel, boolean lowMemory) throws IOException, SignatureNotFoundException {
addChannelByV2(apkFile, apkFile, channel, lowMemory);
}

addChannelByV2 方法的 apkFile 参数是母包文件,channel 参数是需要打包的渠道名称,lowMemory 参数是 V2 签名打渠道包提供的参数,默认为 false。该方法会直接将我们传入的 apkFile 母包修改成 V2 签名的渠道包。如此一来,我们就获得了我们需要的渠道包了。

  • 除了利用 ChannelWriter 类实现打渠道包操作,我们还可以利用 ChannelReader 类来实现读取渠道包的渠道参数,ChannelReader 类提供的 V2 签名渠道包参数读取方法如下:
  public static String getChannelByV2(File channelFile) {
System.out.println("try to read channel info from apk : " + channelFile.getAbsolutePath());
return IdValueReader.getStringValueById(channelFile, -2012129793);
}

getChannelByV2 方法的 channelFile 参数就是打包后渠道包,该方法会返回渠道包中的渠道信息。

最后

感谢您的阅读,希望本文能对您有所帮助。

关注公众号【waynblog】每周分享技术干货、开源项目、实战经验、高效开发工具等,您的关注将是我的更新动力!

服务端apk打包教程的更多相关文章

  1. 基于Angular4+ server render(服务端渲染)开发教程

    目标: 1.更好的 SEO,方便搜索爬虫抓取页面内容 2.更快的内容到达时间(time-to-content) 影响: 1.用户:比原来更快的看到渲染的页面,提升用户体验 2.开发人员:某些代码可能需 ...

  2. 搭建基于.NetFrameWork的私有nuget服务端及打包项目发布上传

    一.私有Nuget服务端搭建 1.创建一个.NetFramework web项目 2.在nuget管理中 安装 nuget.server包 3.安装完成后修改web.config里面的 apikey ...

  3. c#服务端图片打包下载

    一,设计多图片打包下载逻辑:1,如果是要拉取腾讯云等资源服务器的图片,2,我们先把远程图片拉取到本地的临时文件夹,3,然后压缩临时文件夹,4,压缩完删除临时文件夹,5,返回压缩完给用户,6,用户就去请 ...

  4. vue服务端打包及自动部署

    上次给CI环境搭建好了,这次写了一个脚本用于服务端打包及部署使用,解决了前端需要频繁打包的问题,即时将代码推到工程库,服务端自动打包作发布,然后测试人员即时测试,尽早发现问题. 发布原理: 我没有通过 ...

  5. [ABP教程]第一章 创建服务端

    Web应用程序开发教程 - 第一章: 创建服务端 关于本教程 在本系列教程中, 你将构建一个名为 Acme.BookStore 的用于管理书籍及其作者列表的基于ABP的应用程序. 它是使用以下技术开发 ...

  6. Netty4 学习笔记之一:客户端与服务端通信 demo

    前言 因为以前在项目中使用过Mina框架,感受到了该框架的强大之处.于是在业余时间也学习了一下Netty.因为Netty的主要版本是Netty3和Netty4(Netty5已经被取消了),所以我就直接 ...

  7. Vue(服务端渲染)

    一.前言 1.服务端渲染图解                                                 2.简介服务端渲染                             ...

  8. 改造@vue/cli项目为服务端渲染-ServerSideRender

    VUE SEO方案二 - SSR服务端渲染 在上一章中,我们分享了预渲染的方案来解决SEO问题,个人还是很中意此方案的,既简单又能解决大部分问题.但是也有着一定的缺陷,所以我们继续来看下一个方案--服 ...

  9. hubilder打包+C#服务端个推服务实现

    关于推送鼓捣了好长时间,这里不再写helloworld了,只讲里面遇到的问题. 1.关于苹果开发者平台上的注册 网上很多的教程,只要按照步骤来设置就行了,在 iOS证书(.p12)和描述文件(.mob ...

  10. Taurus.MVC 微服务框架 入门开发教程:项目集成:1、服务端:注册中心、网关(提供可运行程序下载)。

    系列目录: 本系列分为项目集成.项目部署.架构演进三个方向,后续会根据情况调整文章目录. 本系列第一篇:Taurus.MVC V3.0.3 微服务开源框架发布:让.NET 架构在大并发的演进过程更简单 ...

随机推荐

  1. 2023-2-22 增加产值冲减和EPC模块

    应集团要求,现在已在综合信息管理系统中已增加以下信息,请大家注意,并及时转告业务人员: 1.[施工合同登记]模块增加必填字段"EPC建安费(万元)""EPC暂列费(万元) ...

  2. 【故障补牢】贪吃的 Bing 爬虫,限量供应的应对措施

    相对于[故障公告],[故障补牢]分享的是园子在发生故障后采取的亡羊补牢措施. 在上次被微软 Bing 爬宕机后(详见 [故障公告]被放出的 Bing 爬虫,又被爬宕机的园子),我们采取了2个应对措施, ...

  3. 2023-02-23:请用go语言调用ffmpeg,解码mp4文件并保存为YUV420P格式文件。

    2023-02-23:请用go语言调用ffmpeg,解码mp4文件并保存为YUV420P格式文件. 答案2023-02-23: 使用 github.com/moonfdd/ffmpeg-go 库. 解 ...

  4. 2020-10-16:CAS知道么?底层实现? 会引发什么问题?如何解决ABA问题?

    福哥答案2020-10-16:#福大大架构师每日一题# 简单回答:cmpxchg原子指令.aba,循环开销大,一个共享变量. [知乎](https://www.zhihu.com/question/4 ...

  5. defer有什么用呢

    1. 简介 本文将从一个资源回收问题引入,引出defer关键字,并对其进行基本介绍.接着,将详细介绍在资源回收.拦截和处理panic等相关场景下defer的使用. 进一步,介绍defer的执行顺序,以 ...

  6. PyCharm-汉化、中文语言包、英文语言包、中英文切换

    PyCharm的汉化是非常简单的,不需要繁琐的步骤,只需要到设置的插件中搜索你需要的语言包安装即可. 登录 进入项目(随便进入一个项目,新建也可以) File->settings->Plu ...

  7. 【工作随手记】mysql优化之1

    原SQL: SELECT p.id, p.NAME, p.idcard, p.phone, p.plate, p.FAMILY_NO FROM t_person_info p WHERE p.id I ...

  8. git解决一个电脑多用户情况(win7)

    首先:在输入ssh-keygen -t rsa -C "注册邮箱"后不要急着按enter,此时输入秘钥对的文件名,不要跟默认文件重名(默认的是id_rsa)

  9. Github疯传!200本计算机经典书籍!

    好书在精不在多,每一本经典书籍都值得反复翻阅,温故而知新! 下面分享几本计算机经典书籍,都是我自己看过的. 重构 改善既有代码的设计 就像豆瓣评论所说的,看后有种醍醐灌顶.欲罢不能的感觉.无论你是初学 ...

  10. 快速上手kettle(三)壶中可以放些啥?

    目录 序言 一 .kettle这壶能装些啥 二.Access输入 2.1 准备Acess数据库和表 2.2 新建一个转换并设置 2.3 启动转换预览数据 三.CSV文件输入 3.1 准备csv文件,并 ...