如何声明Android依赖,确保不打包而由设备运行时提供?
我希望使用Firebase和Play Services库,根据许可协议,我不能将这些库打包进应用分发,只能依赖设备上已存在的版本或引导用户下载。现在的问题是:如何声明依赖,100%确保这些依赖不会被打包进应用,而是由设备提供?
之前我只需要在buildscript中添加classpath依赖,这种方式仅在编译阶段引入:
buildscript { repositories { google() jcenter() } dependencies { classpath 'com.android.tools.build:gradle:4.0.1' classpath 'com.google.gms:google-services:4.3.3' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } }
但现在必须把依赖添加到应用模块的dependencies块中(添加到buildscript不再有效),当前的写法是:
dependencies { implementation platform('com.google.firebase:firebase-bom:31.1.0') implementation 'com.google.firebase:firebase-analytics' implementation 'com.google.firebase:firebase-auth' implementation 'com.google.firebase:firebase-firestore' }
作为Android开发新手,我查了官方文档中Gradle依赖声明的作用:
implementation
Gradle将依赖添加到编译类路径,并打包到构建输出中。
api
Gradle将依赖添加到编译类路径和构建输出中。
compileOnly
Gradle仅将依赖添加到编译类路径(即不会添加到构建输出)。这适用于创建Android模块时,编译阶段需要依赖,但运行时可选的场景。
runtimeOnly
Gradle仅将依赖添加到构建输出,供运行时使用。即不会添加到编译类路径。
我想知道:用api声明依赖能否解决我的问题?
解答
首先明确结论:api不能解决你的问题,只有compileOnly能满足你的需求。
各依赖配置的实际行为拆解:
implementation和api本质都会把依赖打包进APK/AAB,两者仅在是否暴露给上层模块上有区别,官方文档里api的描述没写“打包”只是表述差异,实际仍会将依赖代码打包进应用。compileOnly完全匹配你的要求:编译时提供类文件保证代码能通过编译,但不会将依赖的字节码打包进安装包,运行时完全依赖设备上已安装的对应库。
针对Firebase/Play Services的具体配置:
需将所有具体的Firebase库依赖从implementation改为compileOnly;BOM(版本管理文件)本身不包含实际代码,可保持implementation或改成compileOnly,不影响打包结果:dependencies { // BOM可保持implementation,也可改为compileOnly implementation platform('com.google.firebase:firebase-bom:31.1.0') compileOnly 'com.google.firebase:firebase-analytics' compileOnly 'com.google.firebase:firebase-auth' compileOnly 'com.google.firebase:firebase-firestore' }额外注意事项:
- 运行时必须确保设备已安装对应版本的Google Play Services,否则调用相关API会崩溃,可通过
GoogleApiAvailability类检查服务状态,并引导用户更新或安装。 com.google.gms:google-services插件仍需放在buildscript的classpath中,它负责处理Firebase配置文件(google-services.json),本身不会打包进应用。
- 运行时必须确保设备已安装对应版本的Google Play Services,否则调用相关API会崩溃,可通过
内容的提问来源于stack exchange,提问作者Naan

