当使用gradle 3.x时候,大家会发现,以前引入jar包或依赖modle时所使用的compile,当build时会报出警告,让使用implementation或api。
我和大多数人一样,有强迫症,既然给了提示,就改呗。但是用implementation还是用api呢?试了下,两个都可以用啊,也没报错。
但是查了下,还是有区别的。
implementation:
表明Molde内部使用的jar,相当于class 中的 private。
官方表示:可以增加编译速度(你说能,就能吧,我也懒得测试了)。
个人觉得,可用于解决包冲突问题。
- Modle A 引入了Glide的jar包,使用的implementation;
- Modle B 依赖了Modle A,Modle B 不能访问 Glide 的jar包‘;
api:
与compile相同,只要是同一个项目,modle之间亦可以相互访问。
- Modle A 引入了Glide的jar包,使用的api;
- Modle B 依赖了Modle A,Modle B 可以访问 Glide 的jar包‘;
注意:
当引用jar时,默认的是implementation,在多modle依赖时,注意修改。
compileOnly:
只编译不打包。
当Module A依赖了Module B
Module C依赖了Module A,同时还要依赖Module B;
如果A implementation B, C implementation A 和 B,则会出现依赖冲突。
正确做法应该是:
A compileOnly B,C implementation A 和 B,即A只编译B,不打包B,由C打包A和B。
(个人理解,如果有误,请指正)
通过Androidstudio 可以查看打包后的apk的内容:
如果仅仅只是compileOnly,在运行时肯定会出现NoClassDefFoundError,但在Android Studio中还是能看到该类文件的,只是DefinedMethods为空(如下图)。
NoClassDefFoundError产生的原因:
如果JVM或者ClassLoader实例尝试加载(可以通过正常的方法调用,也可能是使用new来创建新的对象)类的时候却找不到类的定义。要查找的类在编译的时候是存在的,运行的时候却找不到了。这个时候就会导致NoClassDefFoundError.
造成该问题的原因可能是打包过程漏掉了部分类,或者jar包出现损坏或者篡改。