1、从3.4版本的gradle开始,compile已经被api与implementation取代,官网也给出了三者之间的区别:android
图一、api与implementation的区别api
从官网介绍能够看出,implementation可让module在编译时隐藏本身使用的依赖,可是在运行时这个依赖对全部模块是可见的。而api与compile同样,没法隐藏本身使用的依赖。
具体经过例子来看,下图为项目结构:app
项目结构图maven
app依赖模块mylibrary一、mylibrary1依赖模块mylibrary3
mylibrary1以下:ide
package com.example.mylibrary1; /** * @author heshufan * @date 2018/8/9. */ public class MyClass1 { public static String get(){ return "MyClass1"; } }
mylibrary3以下:模块化
package com.example.mylibrary3; /** * @author heshufan * @date 2018/8/13. */ public class MyClass3 { public static String get(){ return "MyClass33"; } }
当mylibrary1 使用api依赖mylibrary3时,gradle
api project(':mylibrary3')
在App中能够直接调用MyClass3类,也就是依赖能够传递。ui
package com.example.heshufan.learnapiandimp; import com.example.mylibrary1.MyClass1; import com.example.mylibrary3.MyClass3; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); MyClass1.get0(); MyClass3.get(); } }
当mylibrary1使用implemention依赖mylibrary3时,设计
implementation project(':mylibrary3')
在App中,没法直接调用mylibrary3code
没法直接调用MyClass3
从上面的例子能够看出,在多module中,implementation确实能够起到隐藏依赖的做用,网上不少的文章都只讲到了这点,那么这样作的目的是什么呢?其实这并非Google设计implemention与api的目的,由于官方文档中说这样设计的目的在于减小build的时间,那么implemention是如何减小build time的呢?
2、咱们再新建一个module:mylibrary4,如今的项目结构如图:
项目结构图
那么如今的项目层级以下图所示:
项目依赖层级图
一、若是mylibrary3使用api依赖mylibrary4,那么当mylibrary4发生变化时,编译须要从新编译mylibrary四、mylibrary三、mylibrary1;
二、若是mylibrary3使用implemention依赖mylibrary4,那么当mylibrary4发生变化时,编译须要从新编译mylibrary四、mylibrary3,这个时候不须要编译mylibrary1,这样就能够节约build time;
为此我验证了两种依赖下项目的build time,每次从新编译前clean project,改变mylibrary4,而后rebuild project,再查看build time。
使用implemention的build time:
implementation
使用api的build time
1api.jpg
能够看到api的build time比implemention多了1秒多,屡次运行都多了1秒多,这仍是在module比较小的状况下。若是包比较多,比较大,那么能够节约的时间是很是可观的。
总结起来:若是api依赖,一个module发生变化,这条依赖链上全部的module都须要从新编译;而implemention,只有直接依赖这个module须要从新编译。
3、如今在回过头来看一下依赖传递的问题,以前验证了使用implemention,app不能拿到MyClass3,这是在本地依赖的状况下,而如今的模块化开发多采用远程依赖的模式进行合做。那么若是采用maven远程依赖呢?
一样采用以前的例子,咱们新建一个module :mylibrary2
mylibrary2
咱们将其上传到咱们的本地maven
maven仓库
最后在mylibrary1中利用implemention依赖mylibrary2
//mylibrary1 implementation 'com.example:mylib:1.0.3'
而后咱们再将mylibrary1上传到本地maven,而后在app中远程依赖mylibrary1
//mylibrary2 implementation 'com.example:myClass2:1.0.0'
也就是app远程implementation mylibrary1,mylibrary1远程implemention mylibrary2,这时候app就能够直接拉到mylibrary2中的myClass2类(命名不规范,别学我)
没有报错
而若是app本地implementation mylibrary1,mylibrary1远程implemention mylibrary2,这时候app则不能获取到mylibrary2中的myClass2类,依然起到了依赖隔离的做用。
由以上能够看到在所有远程依赖模式下,不管是api仍是implemention都起不到依赖隔离的做用。不过,在远程依赖模式下,依赖的一个模块若是版本发生变化,implemention与api的构建速度谁快谁慢还须要进一步研究。
综上,在多层次模块化(大于等于三层module)开发时,若是都是本地依赖,implementation相比api,主要优点在于减小build time。若是只有两层module,api与implemention在build time上并没有太大的差异。
参考资料:
一、https://jeroenmols.com/blog/2017/06/14/androidstudio3/
二、https://www.jianshu.com/p/dd932f951137
做者:一杉先生 连接:https://www.jianshu.com/p/8962d6ba936e 来源:简书 简书著做权归做者全部,任何形式的转载都请联系做者得到受权并注明出处。