赞
踩
如果 B 对 C 使用 implementation 依赖,则 A 无法调用 C 的代码
如果 B 对 C 使用 api 依赖,则 A 可以调用 C 的代码
如果 B 对 C 使用 compileOnly 依赖,则 A 无法调用 C 的代码,且 C 的代码不会被打包到 APK 中
如果 B 对 C 使用 runtimeOnly 依赖,则 A、B 无法调用 C 的代码,但 C 的代码会被打包到 APK 中
实际上每一个组件都有自己的 compileClasspath 和 runtimeClasspath
当一个组件参与编译时,Gradle 就会将其放在 compileClasspath 中
当一个组件参与打包时,Gradle 就会将其放在 runtimeClasspath 中
不同的依赖配置项,其实就是将声明的依赖放入不同组件的不同的 classpath 中,回到上面的例子 对于 implementation ,其实就是将 C 放入 B 的 compileClasspath 和 runtimeClasspath,放入 A 的 runtimeClasspath 中,从而实现 A 如果调用 C 的代码,在 A 的编译阶段 javac 报错,但最终 C 会被打包到 APK 包中
对于 api、compileOnly、runtimeOnly 原理相同
当想要依赖一个源码工程时只需要这样写: implementation project(‘:demo:mylibrary’)
而且我们可以明确知道 mylibrary 中的依赖都会被正确打包到 APK 中
当我们依赖二进制需要这样写: implementation ‘androidx.appcompat:appcompat:1.0.2’
当执行依赖命令(只输出 release 包的 runtimeClasspath):
./gradlew :app:dependencies --configuration releaseRuntimeClasspath > dependencies.txt
输出依赖关系图时会看到并不是仅仅依赖一个 appcompat 组件(只显示部分依赖),还包含该组件自己的依赖,以及依赖的依赖,直到组件自身没有依赖,这样的特性叫做依赖传递
releaseRuntimeClasspath - Resolved configuration for runtime for variant: release
— androidx.appcompat:appcompat:1.0.2
±-- androidx.annotation:annotation:1.0.0
±-- androidx.core:core:1.0.1
| ±-- androidx.annotation:annotation:1.0.0
| ±-- androidx.collection:collection:1.0.0
| | — androidx.annotation:annotation:1.0.0
| ±-- androidx.lifecycle:lifecycle-runtime:2.0.0
| | ±-- androidx.lifecycle:lifecycle-common:2.0.0
| | | — androidx.annotation:annotation:1.0.0
| | ±-- androidx.arch.core:core-common:2.0.0
| | | — androidx.annotation:annotation:1.0.0
| | — androidx.annotation:annotation:1.0.0
| — androidx.versionedparcelable:versionedparcelable:1.0.0
| ±-- androidx.annotation:annotation:1.0.0
| — androidx.collection:collection:1.0.0 (*)
±-- androidx.collection:collection:1.0.0 (*)
±-- androidx.cursoradapter:cursoradapter:1.0.0
那么 Gradle 是怎么确定这些依赖呢?当使用Maven 规范上传组件时,不单单会上传组件的二进制,还会上传一个 pom.xml 文件,依赖信息就在这个文件当中。
因为查看公共的 Maven 服务器有可能需要翻墙,下面给大家展示百度app自己搭建的服务器的后台,方便理解被上传的二进制在服务器是以怎样的结构存放的
这个是百度app自己搭建的 Maven 服务器后台,点击一项查看详情:
有上传的二进制 aar,也有 pom 文件,还有我们在上传时自定义的文件 readme
看完远端的 POM 文件,我们在看看当二进制被下载后在本地是如何存放的
下面是一个简单的 POM 文件:
可以看到有两个 dependency,需要注意的是 scope,也会分为 runtime 和 compile,runtime 不会参与编译,但会参与打包,compile 会参与编译和打包
两个实际例子: 一:假设 A 依赖 B,B 依赖 C
B 对 C 使用 implementation 依赖
B 中有类 Foo 继承于 C中的 Bar
在 A 中使用类 Foo 时会报错找不到类 Bar,解决办法只能让 A 再依赖 C,所以应该尽量避免使用继承
二:假设 A 依赖 B,B 依赖 C
BC 是二进制, B 的 POM 中对 C 的依赖是 runtime
在 Gradle 4.4 中,A 依然可以调用 C 的代码,这个问题在 Gradle 5.0 后被修复
什么是依赖冲突:
假设 ABC 是源码,D 是二进制,A 声明依赖 B,A 声明依赖 C,B 声明依赖 D 1.0 版本,C 声明依赖 D 1.1版本,这时,D 有依赖冲突,需要确定是使用 1.0 还是 1.1 版本
如何解决依赖冲突:
注意:
打包流程 有了前面这些铺垫,让我们实际看看在执行打包 Task 时,实际还执行了哪些 Task。环境配置如下:
Gradle 5.1.1
Android Gradle Plugin 3.1.2
org.gradle.parallel=true 开启并行编译
release 包 minifyEnabled true
执行命令可以得到如下图所示输出
gradlew assembleRelease --dry-run
Task 很多,接下来为大家介绍几个重点的 Task,其余没介绍的感兴趣的同学可以找找对应的实现类,看看它的实现。
描述:做一些编译前的检查
一个例子:有的人可能遇到下面的错误
"Android dependency "+ display+ “is set to compileOnly/provided which is not supported”
这个的原因就是由前面说过的 compileClasspath 和 runtimeClasspath 引起的。
当一个组件因为不同的依赖配置项导致它的 compileClasspath 比如为 1.1.1版本,但他的 runtimeClasspath 是 1.1.2版本,preBuild 就会检测出这个问题并报错我们处理
类:AidlCompile
描述:内部使用 AidlProcessor 调用 call 方法使用 build-tool 下的 aidl 执行编译。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
当我们出去找工作,或者准备找工作的时候,我们一定要想,我面试的目标是什么,我自己的技术栈有哪些,近期能掌握的有哪些,我的哪些短板 ,列出来,有计划的去完成,别看前两天掘金一些大佬在驳来驳去 ,他们的观点是他们的,不要因为他们的观点,膨胀了自己,影响自己的学习节奏。基础很大程度决定你自己技术层次的厚度,你再熟练框架也好,也会比你便宜的,性价比高的替代,很现实的问题但也要有危机意识,当我们年级大了,有哪些亮点,与比我们经历更旺盛的年轻小工程师,竞争。
无论你现在水平怎么样一定要 持续学习 没有鸡汤,别人看起来的毫不费力,其实费了很大力,这四个字就是我的建议!!!!!!!!!
准备想说怎么样写简历,想象算了,我觉得,技术就是你最好的简历
我希望每一个努力生活的it工程师,都会得到自己想要的,因为我们很辛苦,我们应得的。
有什么问题想交流,欢迎给我私信,欢迎评论
内含往期Android高级架构资料、源码、笔记、视频。高级UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter全方面的Android进阶实践技术
)]
内含往期Android高级架构资料、源码、笔记、视频。高级UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter全方面的Android进阶实践技术
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。