Android gradle implementation与api的区别及引用传递
在本篇文章我会先描述使用的场景及结果,然后再做总结,而不是一开始就给出结论,这样大家也比较好理解,也可以自己创建项目运行验证下。
场景一
项目中有三个module,分别叫app、lib1、lib2,依赖关系是app依赖lib1,lib1依赖lib2,假设lib2中有个工具类TestUtils.jave类
如下所示,若lib1用implementation来依赖lib2,则在module app无法引用到lib2中的TestUtils类
dependencies {
implementation project(':lib2')
}
如下所示,若lib1用api来依赖lib2,则在module app中可以引用到lib2中的TestUtils类
dependencies {
api project(':lib2')
}
场景二
项目中有两个module,分别叫app、lib1,依赖关系是app依赖lib1,lib2依赖maven仓库中的lib2,假设lib2中有个工具类TestUtils.jave类
如下所示,若lib1用implementation来依赖maven库lib2,则在module app中无法引用到lib2中的TestUtils类
dependencies {
implementation 'com.himmy.test:lib2:1.0.0'
}
如下所示,若lib1用api来依赖lib2,则在module app中可以引用到lib2中的TestUtils类
dependencies {
api 'com.himmy.test:lib2:1.0.0'
}
场景三
项目中有两个module,分别叫app、lib1,依赖关系是app依赖lib1,lib2通过jar包引用lib2.jar,假设lib2中有个工具类TestUtils.jave类
如下所示,若lib1用implementation来依赖lib2.jar,则在module app中无法引用到lib2中的TestUtils类
dependencies {
implementation files('libs/lib2.jar')
}
如下所示,若lib1用api来依赖lib2.jar,则在module app中可以引用到lib2中的TestUtils类
dependencies {
api files('libs/lib2.jar')
}
场景四
项目中有一个module叫app,app通过maven引用lib1,而lib1中又通过maven引用lib2,假设lib2中有个工具类TestUtils.jave类
如下所示,若lib1用implementation来依赖lib2,则在module app中是可以引用到lib2中的TestUtils类(惊不惊喜,意不意外)
dependencies {
implementation 'com.himmy.test:lib2:1.0.0'
}
如下所示,若lib1用api来依赖lib2,则在module app中可以引用到lib2中的TestUtils类
dependencies {
api 'com.himmy.test:lib2:1.0.0'
}
这是因为lib1不管是通过implementation还是api依赖lib2,生成的pom文件都是相同的,pom文件中都声明了对lib2的依赖
关于如何Android Studio下如何自动打包及上传Maven私服仓库,可以参考这篇文章,Sonatype Nexus Repository Manager OSS仓库管理私服(六)——Gradle自动上传包
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.himmy.test</groupId>
<artifactId>lib1</artifactId>
<version>1.0.0</version>
<packaging>aar</packaging>
<description>lib1</description>
<dependencies>
<dependency>
<groupId>com.himmy.test</groupId>
<artifactId>lib2</artifactId>
<version>1.0.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
场景五
项目中有一个module叫app,app通过maven引用lib1,而lib1中又通过jar包引用lib2.jar,假设lib2中有个工具类TestUtils.jave类
如下所示,若lib1用implementation来依赖lib2.jar,则在module app中是可以引用到lib2中的TestUtils类
dependencies {
implementation files('libs/lib2.jar')
}
如下所示,若lib1用api来依赖lib2.jar,则在module app中可以引用到lib2中的TestUtils类
dependencies {
api files('libs/lib2.jar')
}
lib1上传maven其实是先打包成aar包的,而不管是通过implementation还是api引用jar包,该jar包都会被打包进aar包的,大家可以试着把aar包解压,可以看到打包进入的jar包
总结
- 通过场景一、场景二、场景三可知,不管引用的是module、maven库(其实就是aar包)、还是jar包,implementation都无法实现引用的传递,而api可以实现引用的传递
- 通过场景四可知,maven库中的依赖是可以实现依赖传递的,而不管该库打包前依赖其他库是用implementation还是api声明的
- 通过场景五可知,maven库中依赖的jar包是可以实现依赖传递的,而不管该库打包前依赖的其他jar包是用implementation还是api声明的
其他
compile功能与api一样,可以实现引用传递,但是在新版Gradle中已被废弃,不建议使用
dependencies {
compile project(':lib2')
}