一、前言
bundletool是一个强大的aar包工具,可以对aar包生成apks集合,检测基础apk包大小等等,可参考:bundletool工具使用详解 一文。在本章节,将详细介绍一下如何使用bundletool工具,从aar中获取各种包信息。
二、使用 dump
命令获取aar包各种信息
2.1 关于 dump
命令
可以使用 bundletool help dump
查看bundletool工具的 dump
命令的详细介绍,其中包含样例、信息来源分类以及命令选项,如下所示:
Description:
Prints files or extract values from the bundle in a human-readable form.
Examples:
1. Prints the AndroidManifest.xml of the base module:
$ bundletool dump manifest --bundle=/tmp/app.aab
2. Prints the versionCode of the bundle of the base module:
$ bundletool dump manifest --bundle=/tmp/app.aab --
xpath=/manifest/@versionCode
3. Prints all the resources present in the bundle:
$ bundletool dump resources --bundle=/tmp/app.aab
4. Prints a resource's configs from its resource ID:
$ bundletool dump resources --bundle=/tmp/app.aab --resource=0x7f0e013a
5. Prints a resource's configs and values from its resource type & name:
$ bundletool dump resources --bundle=/tmp/app.aab --resource=drawable/icon
--values
6. Prints the content of the bundle configuration file:
$ bundletool dump config --bundle=/tmp/app.aab
7. Prints the content of the runtime-enabled SDK configuration file:
$ bundletool dump runtime-enabled-sdk-config --bundle=/tmp/app.aab
Synopsis:
bundletool dump <manifest|resources|config|runtime-enabled-sdk-config>
--bundle=<app.aab>
[--module=<base>]
[--resource=<0x7f030001>]
[--values]
[--xpath=</manifest/@android:versionCode>]
Flags:
--bundle: Path to the Android App Bundle.
--module: (Optional) Name of the module to apply the dump for. Only applies
when dumping the manifest. Defaults to 'base'.
--resource: (Optional) Name or ID of the resource to lookup. Only applies
when dumping resources. If a resource ID is provided, it can be
specified either as a decimal or hexadecimal integer. If a resource name
is provided, it must follow the format '<type>/<name>', e.g.
'drawable/icon'
--values: (Optional) When set, also prints the values of the resources.
Defaults to false. Only applies when dumping the resources.
--xpath: (Optional) XPath expression to extract the value of attributes from
the XML file being dumped. Only applies when dumping the manifest.
2.1.1 dump
命令信息来源分类
在命令帮助信息中可以知道,dump
命令的信息来源,主要可分为 manifest
、resources
、config
、runtime-enabled-sdk-config
四种:
manifest
:AndroidManifest.xml
清单文件中获取信息,比如包名、版本号等;resources
:从包体的资源中获取信息,比如定义的字符串等;config
:aar包的配置信息,可获取aar包分割配置、压缩状态等信息;runtime-enabled-sdk-config
:运行时启用的SDK配置信息。
在本篇幅,主要介绍获取manifest
、resources
这两种信息。
2.2 通过 manifest
获取 AndroidManifest.xml
清单信息
aar包中的 AndroidManifest.xml
清单文件是经过加压缩加密的,直接打开无法阅读。对于Android的开发者来说,也可以将aar包拖到AndroidStudio中查阅清单信息。直接使用 bundletool dump manifest
可以输出主模块完整的 AndroidManifest.xml
清单文件内容,但是内容太繁杂,阅读性并不是很好。在前面的 dump
命令帮助信息中我们可以了解到,还有很多命令选项帮助我们过滤信息。对于 manifest
信息,有用的选项参数有以下几个:
--bundle
:指定aar文件的路径--module
:指定aar包内部的模块,获取指定模块的清单(aar可以有多个模块,比如配置了资产分发,每个资产模块都会有清单文件)--xpath
:清单文件中的属性路径,这个是非常有用的,清单路径的根节点是manifest
,最后的属性要以@
符号开头。
2.2.1 获取包名
在aar的清单文件中,包名在根节点manifest
下的 package
属性,获取包名信息,可以使用命令:
bundletool dump manifest --bundle=path_to_aar --xpath=/manifest/@package
命令行输出可以得到清单文件中 manifest
节点下 package
属性的值。
2.2.2 获取版本信息
在aar的清单文件中,版本信息有两个,分别是 versionCode
(整型)和 versionName
(String),分别是在根节点manifest
下的 android:versionCode
属性和android:versionName
属性,于是,命令如下:
// 获取versionCode
bundletool dump manifest --bundle=path_to_aar --xpath=/manifest/@android:versionCode
// 获取versionName
bundletool dump manifest --bundle=path_to_aar --xpath=/manifest/@android:versionName
2.2.3 获取定义的权限列表
在清单文件中,权限是在 manifest
节点下的 uses-permssion
子节点中定义,权限名称是 android:name
属性,于是,使用一下命令可以获取定义的权限列表:
bundletool dump manifest --bundle=path_to_aar --xpath=/manifest/uses-permission/@android:name
- 示例输出
android.permission.INTERNET
android.permission.CHANGE_WIFI_MULTICAST_STATE
android.permission.ACCESS_NETWORK_STATE
android.permission.POST_NOTIFICATIONS
android.permission.READ_EXTERNAL_STORAGE
android.permission.WRITE_EXTERNAL_STORAGE
android.permission.FOREGROUND_SERVICE
android.permission.ACCESS_WIFI_STATE
com.google.android.gms.permission.AD_ID
android.permission.VIBRATE
android.permission.WAKE_LOCK
android.permission.RECEIVE_BOOT_COMPLETED
android.permission.FOREGROUND_SERVICE_DATA_SYNC
com.google.android.finsky.permission.BIND_GET_INSTALL_REFERRER_SERVICE
com.google.android.c2dm.permission.RECEIVE
com.android.vending.BILLING
com.rastargames.zdwjcbt.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION
android.permission.ACCESS_ADSERVICES_ATTRIBUTION
com.huawei.appmarket.service.commondata.permission.GET_COMMON_DATA
2.2.4 获取 Application
类名称
Application
类名称配置在 application
标签下的 androidd:name
属性,那么 --xpath
定义为/manifest/application/@android:name
,于是使用以下命令可以获取Application
类名称
bundletool dump manifest --bundle=path_to_aar --xpath=/manifest/application/@android:name
注意事项:如果命令正确执行,但是输出信息为空,则说明aar包程序中没有自定义
Application
类,即使用了默认的Application
类。
2.2.5 获取 meta-data
信息
meta-data
信息一般配置在 application
标签下, --xpath
定义为/manifest/application/meta-data
,meta-data
信息分为 android:name
(名称) 和 android:value
(值) 两部分,可以使用命令分别获取:
// 获取 meta-data name
bundletool dump manifest --bundle=path_to_aar --xpath=/manifest/application/meta-data/@android:name
// 获取 meta-data value
bundletool dump manifest --bundle=path_to_aar --xpath=/manifest/application/meta-data/@android:value
特别说明:获取
meta-data
信息都是从清单文件的由上而下的顺序读取的,如果所有的meta-data
都包含anroid:name
和android:value
属性,那么使用两个命令分别获取的name列表和value列表,是一一对应关系;如果不能确保都包含这两个属性,不要盲目进行一一对应匹配。
2.2.6 获取各类组件
以此类推,可以获取指定名称的组件,因为组件都是定义在 application
标签下, --xpath
定义为/manifest/application/content_name/@android:name
。
// 获取 Activity组件定义名称
bundletool dump manifest --bundle=path_to_aar --xpath=/manifest/application/activity/@android:name
// 获取 service组件定义名称
bundletool dump manifest --bundle=path_to_aar --xpath=/manifest/application/service/@android:name
特别说明:如果想从清单文件中获取更多信息,bundletool的
--xpath
又无法满足,还有一个更直接的方法,就是不指定--xpath
选项,获取整个清单文件内容,然后通过对 xml 解析,获取更多信息。
2.3 通过 resources
获取资源内容
在本文,主要介绍一下如何从aar包中提取某个名称的字符串值。跟apk不一样,使用aapt工具只能列出字符串表中的所有字符串值,并无发直接根据字符串名称获取对应的值,如果想要从apk中获取某个名称的字符串值,只能使用apktool进行反编译,再从strings.xml
文件中读取。相比之下,bundletool是不是更加方便呢?话不多说,接下来详细介绍下如何根据字符资源名称获取对应的值。
首先,我们先来了解下 resources
可用的命令选项,从前面的帮助信息可以得到:
--bundle
:指定aar文件。--module
:指定模块,如果需要从指定的模块下读取资源,可以通过这个命令选项指定。默认主模块(即:base)--resource
:指定需要查找的资源名称或者ID(可以使用整型或者16进制表示的ID),使用资源名称时,必须使用<type>/<name>
的格式,比如:string/string_resource_name
。--values
:设置此选项,将会打印资源的值,如果没有设置,只会输出支持的语种列表,默认没有设置。
如此一来,通过字符资源的名称获取字符资源,就非常简单了,通过以下命令,可获取aar包中所有支持的语种以及对应的字符资源值:
bundletool dump resources --bundle=path_to_aar --resource=string/common_open_on_phone --values
- 输出示例
Package 'com.rastargames.zdwjcbt':
0x7f10004f - string/common_open_on_phone
(default) - [STR] "Open on phone"
locale: "ca" - [STR] "Obre al telèfon"
locale: "da" - [STR] "?bn p? telefonen"
locale: "fa" - [STR] "??? ???? ?? ????"
locale: "ja" - [STR] "スマートフォンで開く"
locale: "ka" - [STR] "????????? ??????"
locale: "pa" - [STR] "??? '?? ??????"
locale: "ta" - [STR] "???????? ???"
locale: "nb" - [STR] "?pne p? telefonen"
locale: "be" - [STR] "Адкрыць на тэлефоне"
locale: "de" - [STR] "Auf Smartphone ?ffnen"
locale: "ne" - [STR] "????? ??????????"
locale: "te" - [STR] "??????? ??????"
locale: "af" - [STR] "Maak oop op foon"
locale: "bg" - [STR] "Отваряне на телефона"
locale: "th" - [STR] "??????????????"
locale: "fi" - [STR] "Avaa puhelimessa"
locale: "hi" - [STR] "???? ?? ?????"
locale: "si" - [STR] "??????? ??? ????? ?????"
locale: "vi" - [STR] "M? trên ?i?n tho?i"
locale: "kk" - [STR] "Телефонда ашу"
locale: "mk" - [STR] "Отвори на телефонот"
locale: "sk" - [STR] "Otvori? v telefóne"
locale: "uk" - [STR] "В?дкрити на телефон?"
locale: "el" - [STR] "?νοιγμα σε τηλ?φωνο"
locale: "gl" - [STR] "Abrir no teléfono"
locale: "ml" - [STR] "????? ????????"
locale: "nl" - [STR] "Openen op telefoon"
locale: "pl" - [STR] "Otwórz na telefonie"
locale: "sl" - [STR] "Odpiranje v telefonu"
locale: "tl" - [STR] "Buksan sa telepono"
locale: "am" - [STR] "??? ?? ???"
locale: "km" - [STR] "??????????????"
locale: "bn" - [STR] "???? ?????"
locale: "in" - [STR] "Buka di ponsel"
locale: "kn" - [STR] "?????????? ????????"
locale: "mn" - [STR] "Утсаар нээх"
locale: "ko" - [STR] "?????? ??"
locale: "lo" - [STR] "??????????????????"
locale: "ro" - [STR] "Deschide pe telefon"
locale: "sq" - [STR] "Hape n? telefon"
locale: "ar" - [STR] "??? ??? ??????"
locale: "fr" - [STR] "Ouvrir sur le téléphone"
locale: "hr" - [STR] "Otvori na telefonu"
locale: "mr" - [STR] "????? ????"
locale: "or" - [STR] "??????? ???????"
locale: "sr" - [STR] "Отвори на телефону"
locale: "sr-Latn" - [STR] "Otvori na telefonu"
locale: "tr" - [STR] "Telefonda a?"
locale: "ur" - [STR] "??? ?? ??????"
locale: "as" - [STR] "?'?? ????"
locale: "bs" - [STR] "Otvori na telefonu"
locale: "cs" - [STR] "Otev?ít v?telefonu"
locale: "es" - [STR] "Abrir en teléfono"
locale: "is" - [STR] "Opna í símanum"
locale: "ms" - [STR] "Buka pada telefon"
locale: "et" - [STR] "Ava telefonis"
locale: "it" - [STR] "Apri sul telefono"
locale: "lt" - [STR] "Atidaryti telefone"
locale: "eu" - [STR] "Ireki telefonoan"
locale: "gu" - [STR] "?????? ????"
locale: "hu" - [STR] "Megnyitás a telefonon"
locale: "ru" - [STR] "Открыть на телефоне"
locale: "zu" - [STR] "Vula kufoni"
locale: "lv" - [STR] "Atvērt tālrunī"
locale: "sv" - [STR] "?ppna p? mobilen"
locale: "iw" - [STR] "??? ??????"
locale: "sw" - [STR] "Fungua kwenye simu"
locale: "hy" - [STR] "????? ?????????"
locale: "ky" - [STR] "Телефондо ачык"
locale: "my" - [STR] "???????????? ???????"
locale: "az" - [STR] "Telefonda a??n"
locale: "uz" - [STR] "Telefonda ochish"
locale: "fr-CA" - [STR] "Ouvrir sur le téléphone"
locale: "en-GB" - [STR] "Open on phone"
locale: "zh-HK" - [STR] "在手機開啟"
locale: "zh-CN" - [STR] "在手机上打开"
locale: "pt-BR" - [STR] "Abrir no smartphone"
locale: "es-US" - [STR] "Abrir en el teléfono"
locale: "pt-PT" - [STR] "Abrir no telemóvel"
locale: "zh-TW" - [STR] "在手機上開啟"
以上示例输出的字符资源信息中,格式固定,区域 - [STR] "字符资源值"
,(default)
是默认语种,也就是醒目中 values
目录下的字符资源定义。其他的对应区域代码后缀的文件夹下定义的字符资源。
说明:输出示例中的乱码,是因为笔者设备的doc窗口编码,不支持对应语种导致,可以通过设置设备语言来解决。