gradle中compile、api、provided、implementation

一、gralde中compile,api,provided,implementation的区别:

  1. compile ‘com.android.support:appcompat-v7:23.4.0’
  2. provided ‘com.squareup.dagger:dagger-compiler:1.2.1’(网络下载)
  3. provided fileTree(include: ‘*.jar’, dir: ‘…/…/…/core/Base/Gdroid/libs’)(本地路径)
  4. compile files(‘libs/picasso-2.4.0.jar’)
  5. compile project(’:androidPullToRefresh’)
  • compile是从repository(默认是jCenter())里下载一个依赖包进行编译并打包。

  • provided只提供编译支持,但是不会写入apk。比如我在编译的时候对某一个jar文件有依赖,但是最终打包apk文件时,我不想把这个jar文件放进去,可以用这个命令。

  • compile files是从本地的libs目录下寻找picasso-2.4.0.jar这个文件进行编译并打包。类似的命令有compile fileTree(dir: 'libs', include: '*.jar')意思是将libs目录下所有jar文件进行编译并打包。 compile project是将另一个module(等同eclipse中的library库文件)进行编译并打包。

  • api 指令 :完全等同于 compile指令,没区别,你将所有的compile改成api,完全没有错。

注:gradle tools升级到3.0.0以上,compile关键字 已经明确写明废弃了(api关键字的作用等同于之前的compile),但是google官方文档上说“还会保留一段时间,直到下个比较大的gradle tools版本发布”。所以现在仍然使用compile,不会报错。

implementation说明:

implementation指令:这个指令的特点就是,对于使用了该命令编译的依赖,对该项目有依赖的项目将无法访问到使用该命令编译的依赖中的任何程序,也就是将该依赖隐藏在内部,而不对外部公开。

implementation的“访问隔离”只作用在编译期

implementation的“访问隔离”只作用在编译期。什么意思呢?如果lib C 依赖了lib A 2.0版本,lib B implementation依赖了lib A 1.0版本:

  • 那么编译期,libC 可访问2.0版本的libA
    ,libB可访问1.0版本的libA。但最终打到apk中的是2.0版本(通过依赖树可看到)。

  • 在运行期,lib B 和lib C都可访问lib
    A的2.0版本(因为apk的所有dex都会放到classLoader的dexPathList中)。

使用implementation有什么好处

  • 如果项目中有很多级联的工程依赖,比如上图中lib A B C的依赖是工程依赖。如果使用的依赖方式是compile/api,那么当lib A接口修改后重新编译时,会重新编译libA B C(即使lib C中并没有用到修改的libA的接口)。如果使用implementation依赖,因为“编译期隔离”的原因,不相关的lib就不会进行重新编译。

  • 如果项目中都是aar依赖,编译减少时长这个优点就没有了(因为aar已经是编译好的字节码了)。那么还有什么用呢?还是以上图为例。之前我们都是compile依赖,如果lib A已经依赖了lib B,那么在libC的build.gradle中就不用写lib A的依赖了。但这样会有问题:

    1. 我从lib C的build.gradle的依赖列表中不能完整的知道libC都需要依赖哪些lib。
    2. 假设这么一种情况,我知道项目中的依赖的libA的最高版本是2.0,那么app运行时就是使用的这个2.0版本的libA。这时候我需要打一个libC的aar。lib C如果通过compile传递依赖了libA,因此从lib C的build.gradle中不知道lib C 编译时依赖的是哪个版本的lib A。如果libC 打aar(编译)时,依赖的仍然libA 1.0,可能这个aar就有问题了。

你可能感兴趣的:(Android)