AAR

在Android开发阶段中,AAR(Android Archive)是一种用于传递Android库文件的包格式。

AAR文件包含了Android项目的所有组件,如代码、资源文件、AndroidManifest.xml文件等。

通过使用AAR格式,开发者可以将功能模块独立封装,方便重用和共享。

优点

模块化管理:便于将不同功能的代码和资源进行模块化管理。

便于共享:开发者可以方便地将作出的功能打包并分享给团队或开源社区。

避免重复:通过AAR文件,可以避免在多个项目中重复编写相同的代码。

结构

在 Android studio 中双击 aar 文件,就可以查看 aar 文件的结构信息。

example.aar
├── AndroidManifest.xml  # 库的清单文件,描述了库的组件、权限等信息
├── classes.jar          # 编译后的 Java 字节码文件
├── res                  # 资源目录,包含布局、字符串、图片等资源文件
├── R.txt                # 资源索引文件,列出了库中所有资源的 ID
├── assets               # 资源文件目录,可包含任意类型的文件
├── jni                  # 包含本地库(如 .so 文件)的目录
├── proguard.txt         # ProGuard 规则文件,用于代码混淆


APK

APK,全称Android application package,即“Android应用程序包”。

是Android操作系统特有的应用程序包文件格式。包含应用运行所需全部内容,可直接安装到设备上。

它承载着移动应用及中间件的分发与安装使命:要使Android应用程序在设备上顺利运行,必须经过编译与打包成为APK文件,这是Android系统能够识别并执行的关键。
APK文件,作为Android应用程序的包文件格式,虽然外表看似zip格式,但其后缀名已被修改为apk。

通过UnZip解压后,我们可以发现其中包含的Dex文件。Dex,即DalvikVM执行程序,是Android系统特有的字节码,不同于Java ME的字节码。

在Android平台上,DalvikVM的执行文件被打包成apk格式。当程序运行时,加载器会首先解压文件,然后获取编译后的androidmanifest.xml文件中的permission声明,以确定安全访问的限制。

结构

apk文件其实就是一个压缩包,我们可以将apk文件的后缀改为.zip来观察apk中的文件。

example.apk
├── AndroidManifest.xml  # 应用的配置清单文件,描述了应用的组件、权限、图标等信息
├── classes.dex          # 编译后的 Dalvik 可执行文件,包含应用的 Java 字节码
├── res                  # 资源目录,包含布局、字符串、图片等资源文件
│   ├── layout
│   │   └── main_layout.xml
│   ├── drawable
│   │   └── icon.png
│   └── values
│       └── strings.xml
├── assets               # 资源文件目录,可包含任意类型的文件
├── resources.arsc       # 资源映射文件,它包含了应用程序中使用的所有资源的索引信息
├── META-INF             # 存放与 APK 文件的完整性和签名相关的信息
│   ├── CERT.RSA         # 包含 APK 文件的数字签名信息
│   ├── CERT.SF          # 包含 APK 文件中所有资源文件的哈希值和清单文件的哈希值
│   └── MANIFEST.MF      # 是 APK 文件的主清单文件。它包含了与 APK 文件相关的元数据信息,如创建时间、修改时间、版本号等。
└── lib                  # 包含库文件(如 .so 文件)的目录
    └── armeabi-v7a
        └── libnative-lib.so

需要注意

有些 APK 解压后看不到 META-INF 目录,有可能是使用的 V2 的签名,关于Android签名的相关信息可以看Android v1、v2、v3签名详解

https://link.juejin.cn/?target=https%3A%2F%2Fzhuanlan.zhihu.com%2Fp%2F89126018


XAPK

之前的时候,在谷歌商店发布的应用大小是不能超过100MB的,更早的时候甚至不能超过50MB,一些超出了限制的大型软件就需要加obb格式的数据包,很多游戏比如植物大战僵尸2就是这么做的。

因为obb和安装包是分开的,所以如果不在谷歌商店中安装这种应用的话,是需要在安装完安装包后再手动导入obb的。

国外的第三方应用商店apkpure为了解决繁琐的安装过程便基于这种机制开发了xapk格式,并有之对应的安装器方便安装,这就是xapk的来历。

可是尽管通过加装obb数据包这种方法可以突破谷歌商店的大小限制,但随着现在的应用越来越大,只是单纯的堆安装包的大小并不是明智之举,急需一种智能的安装包分发机制——

于是AAB应运而生。

AAB

谷歌宣布

自 2021 年 8 月起,Google Play 将要求开发者以 Android App Bundle (以下简称 AAB)格式发布新应用,该格式将取代 APK 作为标准发布格式。

一直以来,Android 首选的应用程序包就是 APK,而一个 APK 中往往包含应用代码、图片、音频和开发者生成的应用签名密钥等大量资源。

不仅如此,由于 Android 设备规格各异,开发人员还需根据设备的不同屏幕密度(320dpi、480dpi 等)、处理器(ARM、ARM64、x86)、用户所在的不同地区,在 Google Play 中构建和上传多个 APK,以此才能在用户点击“安装”时,在其设备上安装最适配的 APK。

但在这种情况下,应用开发者便承受太多:不仅要开发应用,还要管理许多 APK 以支持大量设备。因此为了省时省力,大多数开发者通常都会选择构建一个通用 APK,即包含语言包、代码等在内的所有资源。不论用户身处何处、使用何种规格的设备,只需下载这个通用 APK 即可。

说到这里,你或许发现了问题所在:包含所有资源的通用 APK 太大了。用户分明只需其中与自己设备相适配的资源,却要把整个 APK 都下载下来,不仅延长了安装时间,也占用了更多的带宽。


为了解决这个问题,谷歌在 2018 年 Google I/O 大会上推出了 AAB 格式,希望以此减少开发者的负担,同时也有助于减少应用大小、安装时间和带宽消耗,提高用户体验。

AAB 格式其实并不是一个全新的应用安装包,你可以将它当做一个容器,里面包含着一个基本 APK 和多个用于特定配置的 APK。

而谷歌在这之中则充当“筛选”的角色:一旦开发者选择使用 AAB 格式发布应用,谷歌就会根据用户的设备配置从中生成优化后的 APK 提供给用户。对用户而言,这样的 APK 体积小、安装快,对开发者来说也省事:不必再为各种设备管理一大堆 APK。


Google play 在下载与更新APK是如何处理按需模块与基本模块的呢?

https://codelabs.developers.google.com/codelabs/on-demand-dynamic-delivery/index.html#7

Note:
To test the download of an on-demand module it's not enough to update the application on the device because the update operation also updates all the on-demand modules that are already installed.
To test the download of the module, you have to uninstall the application and install it again. In this way the on-demand modules are not going to be installed.

可以看出Google Play的下载与更新APK的逻辑很简单,每次下载时都会只下载非按需加载模块,下载了基本模块之后,就可以按需加载其他模块。

如果之后我升级了APK,按需在加载模块是怎么处理的呢?

Google Play会同时为我们更新。这样我们无需为按需加载模块做版本兼容处理。

Base Moudle与 Dynamic Moudle版本永远都会是保存一致,因为Google Play都是基于一个AAB文件构建出APK交付给用户。

使用 AAB 进行发布,将由 Google Play 负责 APK 的生成和签名。并且包体积大小从 APK 的 100M 限制,变为了 AAB 的 150M 限制

AAB 格式无法直接安装在手机上,需要将 AAB 格式转换为 APKS 文件,再安装对应的 APK

  • 更小的应用体积

减小 APK 体积意味着用户能以更少的下载流量和空间获得应用程序。

  • 更少的 APK

不再需要根据地区、机型等区别管理多个 APK。Google Play 控制台会为开发者自动生成和签署 APK。

  • 动态功能模块(Dynamic feature modules)

仅在用户需要时才在应用程序中加载对应功能,即按需加载。

结构

example.aab
├── base                    # 基础模块,包含应用的基本功能
│   ├── manifest            # 与 APK 不同,app bundle 将每个模块的 AndroidManifest.xml 文件存储在这个单独的目录中。
│   │   └── AndroidManifest.xml 
│   ├── lib                 # res/, lib/, and assets/ 这些目录与典型 APK 中的目录完全相同。当上传
│   ├── res                 #  App Bundle 时,Google Play 会检查这些目录并且仅打包满足
│   ├── assets              # 目标设备配置需求的文件,同时保留文件路径
│   ├── root               # 此目录存储的文件之后会重新定位到包含此目录所在模块的任意 APK 的根目录
│   ├── libs                # 存放不同CPU架构的.so文件
│   │   └── armeabi - v7a
│   │       └── libmain.so
│   ├── dex                 # 与 APK 不同,app bundle 将每个模块的 DEX 文件存储在这个单独的目录中
│   │   └── classes.dex
│   ├── assets.pb           # assets.pb、native.pb 和 resources.pb 文件是 AAB 格式的重要部分,它们
│   ├── native.pb           # 描述了 APP 的不同服务目标,动态下发根据这些目标从 drawable/hdpi、
│   └── resources.pb        # lib/armeabi-v7a 或者 `values/es` 等路径中组织不同资源进行下发
├── feature1                    # 表示一个不同的应用模块
├── feature2                    # 表示一个不同的应用模块
├── asset_pack_1                # 对于需要大量图形处理的大型应用或游戏,可以将资产模块化处理为资源包
├── BUNDLE-METADATA     # 此目录包含元数据文件,其中包含对工具或应用商店有用的信息。此类元数据文件可能包含 ProGuard 映射和应用的 DEX 文件的完整列表
├── META-INF
│   ├── ANDROIDD.RSA
│   ├── ANDROIDD.SF
│   └── MANIFEST.MF
├── BundleConfig.pb         # 提供了有关 bundle 本身的信息(如用于构建 app bundle 的构建工具版本)

APKS

apks,即apk split,分散的apk。

现在我们从谷歌商店上下载的应用多半都是apks格式的。

apks格式的安装包,就是使用了Android App Bundle(AAB)技术生成的安装包。

这种技术实际上就是将apk文件拆分成多个小包,再根据当前的设备选择适当的文件下载安装。

通过这种技术,谷歌商店就可以根据我们的设备生成一个适合当前设备的安装包,例如使用大屏幕设备的用户就不需要下载小屏幕的资源,使用arm v8架构设备的用户就不需要下载arm v7架构的资源(当然还存在x86架构的),使用中文的用户就不需要下载其他的语言文件,这样就可以在实现更多功能的同时减小app占用空间的大小。并且为开发者提供了灵活的分发方式和极高的性能。

同时apks将不再支持使用obb数据包拓展软件,这也意味着使用obb数据包的xapk已经成为过去式了。

结构

以MT管理器分析解压一个apks的安装包(FUJIFILM XApp为例)可以发现,它是由很多apk格式的包组合起来的。

XApp.apks
├── base.apk  #主包
├── split_asset_expansion.apk
├── split_config.armeabi_v7a.apk
├── split_config.arm64_v8a.apk
├── split_config.ldpi.apk
├── split_config.mdpi.apk
├── split_config.tvdpi.apk
├── split_config.xhdpi.apk
├── split_config.xxhdpi.apk
├── split_config.xxxhdpi.apk
...
├── split_config.zn.apk
├── split_config.en.apk
├── split_config.ja.apk
├── split_config.tr.apk
...

base.apk:主包,只有它是一个完整的安装包,其他的包依附于它。base.apk通常只用来存放classes.dex代码、AndroidManifest.xml配置文件、签名文件、控件等,而大部分资源文件放在了其余的包里。

可以看到其他的包是以split开头的,也就是分包,是根据你的设备自动分配的。

split_asset_expansion.apk:扩展包,用于存放应用程序所需要的额外的资源文件,比如贴图、音频、视频及其他大型数据文件。

split_config.armxx.apk:是架构so文件包,是根据的手机架构而自动分配的。比如你的手机是arm v8设备,那这个包中就会只放置arm v8的so文件;是arm v7就会变成arm v7的so文件。对应原apk安装包中的lib文件夹

split_config.xxhdpi.apk是图标包,会根据你手机横纵尺寸的DPI自动分配。对应原apk安装包中的res文件夹

split_config.zh.apk是语言包,会根据手机当前的语言自动分配。对应原apk安装包中的arsc文件

参考文章

https://juejin.cn/post/7470004847184330787

[Android 原创] 安卓逆向入门笔记(一)——apk文件结构-吾爱破解论坛

android studio中的aar是什么——51CTO

关于Apks的一切|MT管理器|NP管理器|SAI

Android App Bundle解析——知乎

https://finance.sina.com.cn/tech/2021-07-01/doc-ikqciyzk2983800.shtml?_zbs_baidu_bk

https://juejin.cn/post/7484083122000576566

Android App Bundle 技术介绍及详细使用教程Android App Bundle 是什么? Androi - 掘金

探索 APK 文件的内部:了解 Android 应用程序的组织结构_apk如何查看文件构成情况-CSDN博客

Android App Bundle:动态功能模块-腾讯云开发者社区-腾讯云

Google aab生成格式剖析App Bundle 文件格式 1. 基本文件格式结构 解压后的 AAB 中的内容和 A - 掘金

Android App Bundle 格式  |  Google Play  |  Android Developers