Android Archive通常指AAR格式的归档包,它是Android Library模块发布后的标准产物。AAR文件本质上是ZIP压缩包,内部包含编译后的Java或Kotlin字节码、Android资源、清单文件片段、R.txt以及混淆规则等内容。与普通JAR不同,AAR携带了Android平台特有的资源与元数据,因此仅对源码执行单元测试并不能证明最终归档产物可以正常被消费工程集成。发布后常见的资源找不到、Manifest属性冲突、R类字段缺失等问题,很多都源于归档包结构不完整或内容没有被单独验证。围绕AAR的测试需要覆盖结构校验、公开API验证、消费工程集成测试以及发布前完整性检查,只有形成完整的测试链路才能降低组件库交付风险。

一、拆开AAR:归档结构测试是第一步
AAR的目录结构直接决定了消费工程能否顺利解析。标准AAR至少包含classes.jar、AndroidManifest.xml、res目录、R.txt以及可选的proguard.txt、libs目录和jni目录。测试第一步应当把生成的AAR当作黑盒解压,确认必要条目是否齐全。可以先在本地构建成功后找到build/outputs/aar下的文件,再通过解压命令查看内部列表。
unzip -l mylibrary-release.aar
这一步看起来简单,却能快速发现构建配置错误。例如某个Library Module没有把资源参与打包,res目录就会缺失;如果Manifest没有正确合并,AndroidManifest.xml可能只有空壳。结构测试还应校验AndroidManifest.xml中的package属性、minSdkVersion与targetSdkVersion是否符合发布预期,以及R.txt中是否包含所有公开资源符号。尤其是提供UI组件的库,如果R.txt里缺少某个styleable字段,消费工程在编译期引用该属性时会直接失败。
更可靠的发布流程可以把结构检查写进Gradle Task或CI脚本。例如解压后使用grep检查AndroidManifest.xml中的<uses-sdk>内容,或者解析R.txt判断关键的资源ID是否生成。可以设置自动化门槛:AAR中若没有classes.jar或R.txt就直接终止发布。这样能在构建完成后的第一时间拦截不完整产物,而不是等到接入方编译报错后再回滚。
二、库模块单元测试与公开API验证
对Library Module本身运行单元测试是保证AAR内部逻辑正确的基础。Gradle构建会把Library Module作为Android Library处理,单元测试通常放在src/test目录下,依赖JUnit和Robolectric等框架。需要注意的是,单元测试执行的是模块源码编译后的类,但它和最终打进AAR的classes.jar有一定差异,尤其是当模块使用了transform或字节码修改工具时,测试结果未必等同于产物行为。
公开API验证是归档测试中容易被忽略的一环。一个AAR被消费工程依赖后,只有public类和方法对调用方可见。如果内部实现类没有从公开接口中移除,不仅会扩大攻击面,还会在混淆后产生NoClassDefFoundError。建议在发布前显式声明公开API规则,例如使用Gradle配置consumerProguardFiles,让消费工程在编译时强制应用混淆规则。开发者可以用以下方式在library模块中关联消费者规则。
android {
defaultConfig {
consumerProguardFiles 'consumer-rules.pro'
}
}
dependencies {
testImplementation 'junit:junit:4.13.2'
}同时在consumer-rules.pro中保留需要暴露的API,例如使用keep规则保留包名下的公共接口。除了混淆规则,单元测试还应该覆盖序列化与Parcelable实现、异常路径和资源工具类。对于提供复杂SDK的AAR,这一层测试可以配合Mockito或Robolectric验证回调时序和状态管理,减少宿主App集成后才发现逻辑缺陷的概率。
三、将AAR导入消费工程做集成验证
单元测试通过不代表AAR可以在真实App中运行。第二步和第三步之间最关键的差异是消费工程的Manifest合并、资源合并和依赖解析。发布前应当创建一个最小的示例工程,使用implementation files或maven坐标引入待测试AAR,然后执行assembleDebug和connectedAndroidTest。
dependencies {
implementation files('libs/mylibrary-release.aar')
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
}集成测试至少应验证三件事。第一是资源是否能被正常索引,包括通过R类访问的资源ID和运行时通过Resources获取的字符串、颜色、图片。第二是Manifest合并是否符合预期,例如Library声明的Activity、Service或权限是否被正确并入宿主Manifest,有没有因为tools:replace配置缺失导致构建失败。第三是AAR中的依赖是否传递完整,特别是使用了compileOnly声明的依赖如果未在文档说明,消费工程会因缺少运行时类而崩溃。
可以用一段简单的AndroidJUnitRunner测试来验证资源加载是否成功。
@RunWith(AndroidJUnit4.class)
public class AARIntegrationTest {
@Test
public void checkResourceAndApi() {
int nameRes = com.example.mylibrary.R.string.lib_name;
assertNotEquals(0, nameRes);
String value = ApplicationProvider.getApplicationContext().getString(nameRes);
assertNotNull(value);
}
}如果Library包含自定义View,还需要在测试布局中实际加载该View并执行测量、绘制流程,确保res目录和attr属性没有缺失。只有经过消费工程的真实集成测试,才能发现单元测试阶段无法覆盖的资源链接和Manifest合并问题。
四、发布前归档完整性检查与常见误区
当AAR准备对外发布时,除了功能测试,还需要检查归档内容是否干净、体积是否合理、依赖是否冲突。常见的完整性检查包括使用jar tf查看classes.jar中的包路径,确认没有把内部测试类或示例代码打进正式产物;检查AAR中是否包含libs目录下的重复依赖,避免与消费工程已有依赖发生版本冲突;扫描jni目录确认不同ABI的so文件命名是否一致。
在归档测试中存在几个高频误区。第一个是把源码编译通过误认为归档可用,源码编译通过只能证明Library Module自身能被编译,不能反映AAR打包后的资源、Manifest和依赖关系是否正确。第二个是忽略混淆产物测试,很多Library会在发布时开启minifyEnabled,但测试却只针对未混淆的debug包,导致混淆后公开API被裁剪。第三个是缺少对发布依赖范围的控制,使用api和implementation声明的依赖在AAR中传递行为不同,如果错误地把运行时必需依赖声明为implementation,消费工程在运行时可能找不到类。
- 发布前检查classes.jar中是否包含预期外的内部类
- 验证AAR中的proguard.txt和consumer-rules.pro内容一致
- 对AAR体积设定阈值,防止无用资源和重复so文件进入归档
- 用最小示例工程执行一次assembleRelease,确保消费方打Release包也不会失败
将结构校验、单元测试、集成测试和发布检查串成自动化流水线后,AAR的交付质量会有明显提升。开发者可以针对每个环节设置独立的CI Job,只有当AAR结构完整、单元测试通过、示例工程连接测试通过且完整性扫描无告警时才允许发布。这样的归档测试策略不仅降低了接入方的集成成本,也能让组件库在后续迭代中保持稳定。
Android Archive归档测试AAR包修改时间:2026-08-25 01:50:07