Android App Bundle 自动打包原理

2023-05-16

Google推出Android App Bundle 已经有一段时间了。 根据Google的政策说明 ,预计2021年8月之后,新发布的应用都必须使用Android App Bundle(aab)来上架Google Play Store了。

对于Android App Bundle的原理,Google官方文档已经有了很详细的介绍, 想了解的同学建议直接阅读Google的官方文档。

如果你是使用Android Studio打包,那么你直接在Android Studio中选择构建App Bundle即可将应用打包成aab了。

这篇文章,我们主要介绍如何在U8SDK聚合打包工具中生成aab格式的文件(新版本的U8SDK打包工具已经支持aab打包了)。

一、文件格式介绍

aab——Android App Bundle格式文件,也就是一个有固定目录格式的压缩文件。

我们以一个demo.aab为例,将其解压,我们看下其中的目录结构:

--BundleConfig.pb  : 打包bundle的时候,自动生成
--base  : base目录
------assets:         对应apk的assets目录
------dex:             原apk中classes.dex,classes2.dex...都放这里
------lib: 原apk中lib目录都放这里
------manifest: 原apk的AndroidManifest.xml放这里,需要是编译后的AndroidManifest.xml
------res:apk中的资源放这里,需要是编译后的资源
------root: apk中相对于根目录的其他资源文件
------resources.pb:编译资源的时候会生成的
------assets.pb:编译bundle的时候会生成的
------native.pb: 编译bundle的时候会生成的

二、如何打包生成aab

了解过U8SDK打包原理的同学应该知道,在U8SDK打包工具中,我们将母包apk反编译,然后合并进去对应的渠道SDK的代码、资源、so文件等,然后再将合并后的内容回编译成最终的apk。

在U8SDK打包工程中直接打出aab的原理其实就一句话——要生成aab,我们只需要将合并后的目录(decompile目录), 转换为上面aab打包需要的资源目录格式即可。

所以整个适配过程如下(这里不贴python脚本,只说原理过程~😄):

1、编译资源

首先,我们需要将decompile目录下的res进行编译。 编译资源我们需要使用aapt2,并且需要将资源编译生成protobuf格式的版本。


使用aapt2编译资源,我们需要先执行compile命令,再执行link命令:

aapt2 compile --dir ./res -o ./compiled_resources

aapt2 link --proto-format -o baseapk -I ../android.jar --manifest .\AndroidManifest.xml -R .\compiled_resources\*.flat --auto-add-overlay

执行上面的命令之后, 我们就在decompile目录下,生成了base.apk。 我们需要将这个apk解压。 
解压后里面的目录格式如下:

--res
--AndroidManifest.xml
--resouces.pb

我们就以这个目录作为base目录, 后面拷贝的资源都拷贝到这个目录里面来。 

按照上面的bundle目录结构,我们在这个目录下,新建一个manifest目录,然后我们将AndroidManifest.xml拷贝到manifest子目录下。

现在base的目录结构如下:


--res
--manifest
------AndroidManfiest.xml
--resources.pb

2、编译dex

我们打包过程中合并后的代码格式是smali格式, 经过u8sdk打包脚本的自动dex拆分后,在decompile目录下的代码目录结构是smali、smali_classes2、smali_classes3...

我们需要将这些smali目录编译生成对应的classes.dex、classes2.dex、classes3.dex...

我们使用smali.jar进行这步操作,smali.jar可以从github上下载,或者加U8SDK技术交流裙(扣:1055996444)索要。

对所有smali目录执行如下命令,就可以将dex生成到base目录下了
 

java -jar smali.jar assemble -o ./base/dex/classes.dex ./smali

生成之后,base目录结构如下:

--res
--manifest
------AndroidManfiest.xml
--dex
------classes.dex
------classes2.dex
--resources.pb

3、拷贝其他资源

这一步就更简单了, 我们需要将decompile目录下其他对应目录中的内容,直接拷贝到base目录下对应的子目录中即可。 对应的拷贝目录关系如下:

decompile/assets ==>  base/assets
decompile/lib ==> base/lib
decompile/unknown ==> base/root

拷贝之后, 我们的base目录结构如下图:

--assets
--lib
--root
--res
--manifest
------AndroidManfiest.xml
--dex
------classes.dex
------classes2.dex
--resources.pb

4、编译bundle

打包生成aab文件,我们需要使用bundletool.jar,这个文件你可以Google官网或者github上下载,或者加U8SDK海外交流群(扣)索要。

上面的base目录结构已经准备好了,我们将这个目录压缩成base.zip,接下来我们就可以使用bundletool.jar生成aab文件了

java -jar bundletool.jar build-bundle --modules= ./base.zip --output=./output.aab

跟着流程到这里,我们的output.aab就是一个纯正的aab文件啦~

5、签名bundle

如果你需要将bundle发布到Google Play平台,还需要对你的aab文件进行签名, 只能使用jarsigner进行签名哦,不可以使用apksigner。

jarsigner -digestalg SHA1 -sigalg SHA1withRSA -keystore test.keystore -storepass 123456 -keypass 123456 ./output.aab test


三、如何测试生成的aab

1、生成apks

打出了bundle之后, 如果我们本地想测试这个bundle的功能是否正常怎么办呢?我们依然使用bundletool.jar来完成。

我们用bundletool.jar将我们的bundle编译生成apks,注意不是apk,是apks。

java -jar bundletool.jar build-apks --bundle=./output.aab --output=./output.apks

这样就生成了apks文件,apks文件你可以解压看下,里面是一群根据特性拆分后的apk文件。

2、部署到设备

然后,我们可以将apks部署到设备上,进行安装测试。 我们可以将设备通过USB连上电脑,然后依然使用bundletool命令:

java -jar bundletool.jar install-apks --apks=./output.apks

这样就完成了bundle的打包以及本地测试了。 如果你对这块感兴趣或者还有疑问,可以加入U8SDK的海外交流裙(扣:1055996444)哦。


 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android App Bundle 自动打包原理 的相关文章

  • 错误:没有这样的属性:类的manifestPlaceholders:com.android.build.gradle.management.ProductFlavor

    I use gradle experimental 0 4 0 我想在我的项目中使用 onesignal sdk 当我尝试使用此处示例中提到的代码构建项目时 我收到此错误 错误 没有这样的属性 类的manifestPlaceholders
  • 安卓市场API

    有谁知道Android市场是否有一个API 可以自动提交新应用程序 而无需手动填写市场表格 不 抱歉 没有程序化的方式来提交市场列表 据推测 这是一种反垃圾邮件发送者措施
  • 如何将图片保存到文件中?

    我正在尝试使用标准意图来拍照 然后允许批准或重新拍摄 然后我想将图片保存到文件中 这是我正在使用的意图 Intent intent new Intent android provider MediaStore ACTION IMAGE CA
  • 从本机代码访问 AsyncStorage

    我需要使用 JS 代码中的 AsyncStorage 将数据保存在本地存储中 我想知道是否有一种方法可以从本机代码 Objective C 或 Java 访问 AsyncStorage 存储的数据 Thanks 如果你导入RCTAsyncL
  • android以编程方式打开电池设置

    我正在寻找一种从 Android 应用程序打开电池设置屏幕的方法 到目前为止我发现了两个意图 Intent ACTION POWER USAGE SUMMARY Settings ACTION BATTERY SAVER SETTINGS
  • 使用 navhost 停止底部导航中的片段刷新

    这个问题已经被问过几次了 但现在已经是 2020 年了 有没有人找到一个好的可用的解决方案呢 我希望能够使用底部导航控件进行导航 而无需在每次选择片段时刷新片段 这是我目前拥有的 导航 main xml
  • Android SIP 客户端 SipManager.open() 未打开

    我一直在使用 Android SDK 的本机 SIP 库编写 SIP 客户端 由于某种原因 我无法让我的帐户在服务器上注册 以下是测试场地 Linux Mint 17 XFCE 运行 Kamailio 服务器 启用 MySQL 和 TLS
  • 将 REST 服务与 Android 应用程序同步

    我使用一个 REST 服务来填充数据库中的信息 稍后由我的应用程序使用 我已经阅读了有关此事的多个主题 现在必须决定如何在 REST 服务和数据库之间实现同步 想象一个应用程序 它从谷歌金融 API 获取有关股票的信息并将其存储在数据库中
  • Android 4.3 的 Google 地图 Android API V2 问题

    我是谷歌地图的新手 刚刚点击此链接http www androidhive info 2013 08 android working with google maps v2 http www androidhive info 2013 08
  • 将 EditText 聚焦在设备上运行的 PopupWindow 中时出现异常

    我正在为 Android 开发一个弹出窗口 它正在工作 我在上面添加了一个 EditText 和一个按钮 当在 ADV 上运行时 它可以正常工作 而在设备上运行时 当我专注于 EditText 时 这会抛出一个奇怪的异常 android v
  • 在 Facebook 上分享文本和 URL

    我想分享一条消息 例如 查看图片http someUrl com http someUrl com从应用程序共享ABCapp 用户必须能够选择任何已安装的应用程序进行共享 我正在使用以下代码 Intent intent new Intent
  • SlidingPaneLayout setCoveredFadeColor () 和 setSliderFadeColor()

    我正在使用SlidingPaneLayout并希望在滑块右窗格打开时在左窗格上设置灰色渐变颜色 在右窗格关闭且左窗格完全可见时在左窗格上设置透明渐变颜色 我知道这是默认行为SlidingPaneLayout 但使用默认实现时 我在横向模式下
  • 文本转语音无法在 Android 设备上运行

    下面是我的代码 我无法在 Kitkat 设备中听到声音 Toast 出现 但声音没有播放 我正在遵循本教程 https www tutorialspoint com android android text to speech htm ht
  • 设置 JAVA_HOME 变量时出现问题

    所以我刚刚下载了 Android Studio 并尝试设置 JAVA HOME 变量以便我可以运行它 我使用的是 Windows 8 并按照我找到的所有说明进行操作 但无济于事 转到高级系统设置 gt 环境变量 然后使用包含我的 jre7
  • 在 Android 中使用 Fragment 时处理后按

    我在应用程序中使用 Android 滑动菜单和导航抽屉 并且在应用程序中使用片段而不是活动 当我打开抽屉时 单击一个项目会出现一个片段 我使用以下代码从一个片段移动到另一个片段 Fragment fragment null fragment
  • Android 中的垂直(旋转)标签

    我需要两种在 Android 中显示垂直标签的方法 水平标签逆时针旋转 90 度 字母在侧面 带有字母的水平标签 如商店招牌 我是否需要为这两种情况 一种情况 开发自定义小部件 我可以使 TextView 以这种方式呈现吗 如果我需要完全自
  • Android 2.2 中不带预览的相机捕获

    我需要捕获图像而不显示预览 我想在后台作为服务来完成它 可以这样做吗 是有可能实现的 您应该定义一个处理 Camera 对象的类 例如调用 Camera open 等 不要为相机对象提供以下行以禁用预览 mCamera setPreview
  • 在 Android Studio 中打开上次关闭的选项卡

    我是 Android Studio 的新手 想知道是否有任何快捷方式 选项可以重新打开上次关闭的选项卡 没有分配快捷方式 但您可以轻松分配新的快捷方式 Go to IDE settings Keymap Main menu Window E
  • react-native-firebase 无法处理通知 click_action 导航到通知屏幕

    我正在使用这个react native firebase和react navigation进行导航 我可以成功地从服务器或控制台推送通知 无论它是在前台还是后台 但我发誓文档不太清楚如何打开通知并导航到通知它所属的屏幕 这些是我的 onMe
  • 水平 RecyclerView 顶部的滚动条

    我正在做简单的演示卧式RecyclerView 我想与回收视图一起显示滚动条 所以我添加了android scrollbars horizontal and android scrollbarSize 5dp 在 XML 中 我可以获得滚动

随机推荐

  • B站Unity官方教程合集(不定期更新)

    Unity官方有好多教程 xff0c 可以帮助我们快速掌握这款引擎的使用 xff0c 但官网上的视频都是油管的 xff0c 故这里为大家整合了一些在B站上的搬运视频 xff0c 很多还是有翻译字幕的 xff0c 比搭梯子方便多了 xff08
  • STM32连接HT1621段码屏驱动

    HT1621 128个位元LCD控制器 xff0c 内部RAM直接对应LCD显示单元 对于HT1621 操作之前应发送标志码 xff0c 表明要求工作在哪种状态 xff0c 标志定义如下 xff1a 操作状态标志码读数据110写数据101读
  • RTK与PPK

    1 通讯方式不同 RTK技术需要无线电台或网络来传输差分数据 PPK技术不需要通信技术的支持 xff0c 并且可以记录静态数据 2 定位方法不同 RTK所使用的实时定位技术使您可以随时在流动站上查看测量点的坐标和精度 xff1b PPK定位
  • iOS真机调试报错(0xE8008016)相关错误

    经常真机运行时候会报错 xff0c 原因之一是之前对项目进行过打包进行如下设置 将Edit Scheme gt Run gt Build Configuration 设置为Release 将其勾选为 Debug状态 xff0c 接下来继续运
  • 支付宝快捷登录相关事宜

    接近年关 xff0c 公司产品提出新需求 xff0c 和支付宝合作 xff0c 需要开发快捷登录 无线账户授权 xff0c 手机端装有支付宝钱包 xff0c 直接唤起支付宝钱包 xff0c 若没有支付宝钱包就直接走HTML5页面操作 xff
  • mac系统Tunnelblick 下载以及安装流程

    公司有些网站有权限设置 xff0c 不同的域账号权限不一样 xff0c 因此需在电脑上安装Tunnelblick xff0c 才能使用 xff0c 接下来给大家介绍一下步骤 xff1a 首先要有安装vpn对应的一系列配置文件 xff1a c
  • IOS App提交到appStore Missing 64-bit support

    Dear developer We have discovered one or more issues with your recent delivery for 34 就医宝 34 Your delivery was successfu
  • MAC 安装cocoapods

    首先是看了文章 xff1a http code4app com article cocoapods install usage http www uml org cn mobiledev 201411072 asp 一 检测以及配置Ruby
  • U8SDK——开发统一的手游防沉迷插件

    关于统一防沉迷插件的配置和使用 xff0c 可以参考我们B站上面录制的视频教程 未满18岁那个视频 xff1a U8SDK官方视频 根据手游防沉迷和实名认证政策的要求 xff0c 手机游戏需要引导玩家进行实名认证 xff1b 同时针对未成年
  • Unable to run app in Simulator(Domain = LaunchServicesErrror, Code = 0)

    NSArray paths 5 61 NSSearchPathForDirectoriesInDomains NSLibraryDirectory NSUserDomainMask YES Users hkqj Library Develo
  • 微信支付登录总结

    做微信支付 xff0c 登录之前需要 提前注册开发者帐号 xff0c 创建移动应用 代码下载路径 xff1a http pan baidu com s 1o7aBxqU xff08 主要是做笔记 xff0c 把微信登录以及微信支付整到一起
  • 微软仿真神器 AirSim + Unreal Engine 4.24 + Ubuntu 18.04 + ROS 编译流程小结

    时间 xff1a 20210107 文章目录 一 参考资料二 系统情况简介三 编译UE引擎流程四 UE引擎测试五 AirSim编译流程六 UE 4 24 43 AirSim 联合测试七 AirSim 的 ROS 功能包测试八 UE 43 R
  • android进阶---【注解(一)之运行时注解】

    android进阶 注解 注解1 什么是注解2 注解的产生3 注解的基础介绍3 1元注解3 2运行时注解与编译时注解区别 4 自定义注解4 1自定义编写规则4 2自定义运行时注解 注解 注解这个概念 xff0c 有些人可能会有些陌生 但是撸
  • 设计容器 实现put get getCount 方法,生产者消费者问题

    设计一个容器 xff0c 支持put get getCount 方法 xff0c 满足两个生产者 二十个消费者阻塞调用 public class ProdConsuCont static ReentrantLock lock 61 new
  • C++程序员必看书单

    转载 xff1a https blog csdn net ljy1988123 article details 7748913 comments C 43 43 xff1a Prata C 43 43 Primer Plus xff1a 基
  • git submodule 升级commit并push

    git submodule 升级commit并push 关于这个问题 xff0c 可以参照以下文章 xff1a https blog csdn net wwj 748 article details 73991862 流程写的很清楚 xff
  • 欧拉角pitch、yaw,roll的理解

    关于旋转永远是做游戏的难点和混乱点 我们知道表示一个旋转有多种方式 xff0c 简单的欧拉角 xff0c 复杂点的四元数 xff0c 再复杂点的矩阵 之前接触unity可以用四元数和欧拉角两种方式表示旋转 xff0c 最近一直研究虚幻引擎
  • Mac执行ruby命令提示 dyld: Library not loaded等类似问题解决方案

    说一下为啥会遇见这么个问题 xff0c 我在给一个xcode项目添加podfile的时候 xff0c 在终端执行了pod init命令 xff0c 随即给了我一个如下图的提示 xff08 报错信息一样的 xff0c 执行pod的命令早就被解
  • 编程题:多线程交替打印ABC

    要求创建3个线程 xff0c 分别打印ABC xff0c 共交替打印10次 span class token keyword public span span class token keyword class span span clas
  • Android App Bundle 自动打包原理

    Google推出Android App Bundle 已经有一段时间了 根据Google的政策说明 xff0c 预计2021年8月之后 xff0c 新发布的应用都必须使用Android App Bundle aab 来上架Google Pl