应优先使用implementation,仅当模块公共API直接引用依赖类型且需被上层模块使用时才用api;前者限制编译期依赖传递、缩短构建时间并避免耦合,后者则导致修改底层依赖时触发大量模块重编译。

关键在于区分“谁要用”和“谁能看到”。implementation 让依赖只在当前模块内可用;api 则让依赖对所有上层模块也可见——这是控制编译期依赖传递的核心机制。
什么时候用 implementation
绝大多数情况下该选它。只要依赖仅用于实现当前模块的内部逻辑,不对外暴露接口,就用 implementation。
- 比如一个工具类库(如 Gson、OkHttp)只在你的 library 模块里做 JSON 解析或网络请求,外部 app 模块不需要直接调用这些类,那就用 implementation
- 它能缩短编译时间:改了这个依赖的 API,Gradle 只需重新编译当前模块,不会触发上层模块的增量编译
- 避免意外耦合:防止其他模块误用你不打算公开的底层依赖,提升模块边界清晰度
什么时候必须用 api
只有当你模块的公共 API 直接引用了某个依赖的类型,并且调用方(比如 app 模块)需要使用这些类型时,才用 api。
- 例如你写了一个 NetworkManager 类,它的方法返回 Retrofit.Call<Response>,那 Retrofit 就必须用 api 声明——否则 app 模块编译时会报错“无法解析 Call 类”
- 再比如自定义 View 继承了第三方 UI 库的基类,或者接口参数/返回值是依赖库中的类,这类场景都要求依赖可传递
- 注意:用了 api 后,一旦该依赖升级或修改了公开 API,所有依赖你的模块都可能需要重新编译
常见误用与验证方法
判断配置是否合理,最直接的方式是看编译结果:
立即学习“Java免费学习笔记(深入)”;
- 在上层模块(如 app)里尝试 import 下层模块用 implementation 引入的库中的类——如果编译失败,说明生效了;如果成功,说明你本该用 api 或者配置有误
- 检查模块的 AAR 或 jar 输出:implementation 依赖不会出现在其 POM 文件的 dependencies 列表中;api 会列出
- Android Studio 的 Project Structure → Dependencies 视图里,implementation 依赖显示为 “(not exported)”,api 依赖则无此标记
替代旧 compile 的注意事项
compile 已被废弃多年,不能混用:
- Gradle 4.1+(对应 AGP 3.0+)起,compile 报错并强制替换为 api 或 implementation
- 不要以为 api 就是“兼容 compile”,而是要主动思考:这个依赖到底要不要被别人看到?不是“怕出错就全用 api”,而是“没理由暴露就用 implementation”
- java-library 插件是 api 的前提;纯 java 插件不支持 api,需显式 apply 'java-library'


















