在发版之前,我们需要关注的一个指标是包体积,作为一个模块化的项目,如果各模块是以aar的方式依赖到主项目(壳儿)中,那么你可以使用如下的方式来分析两个版本之间的aar文件差异,并输出结果。
效果图
使用方式
Root/build.gralde
1 2 3 4 5 6 7 8
| buildscript { repositories { maven { url "https://jitpack.io" } } dependencies { classpath 'com.github.JuneLeo:dependencies-diff:1.1.2' } }
|
Project/build.gradle
版本一(分支1)
1 2 3 4 5
| //输出到根目录 dependencies.csv task dps(type: com.card.script.get.DependenciesGetTask){ exclude = ["support"] classpath = 'runtime' // compile,runtime,all }
|
版本二(分支2)
1 2 3 4 5 6 7 8 9 10 11 12
| //输出到根目录dependencies.csv task dps(type: com.card.script.get.DependenciesGetTask){ exclude = ["support"] classpath = 'runtime' // compile,runtime,all } // 比较两个dependencies.csv并输出html task dps2(type:com.card.script.diff.DependenciesDiffTask){ firstPath='/Users/juneleo/amap/amap_android/dependencies.csv' secondPath='/Users/juneleo/amap/amap_android_backup/amap_android/dependencies.csv' outType='html' //html,console excludeModuleFile =['/arm64-v8a/'] // 过滤文件 }
|
原理
收集项目依赖
1.获取项目依赖的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| // 获取项目编译时的依赖 Configuration compileClassPathConfiguration = getProject().getConfigurations().getByName(variantName + "CompileClasspath")
// 获取项目运行时的依赖 Configuration runtimeClassPathConfiguration = getProject().getConfigurations().getByName(variantName + "RuntimeClasspath")
// 获取所有的不重复的依赖 集合 Set<ResolvedComponentResult> resolvedComponentResults = compileClassPathConfiguration.getIncoming().getResolutionResult().getAllComponents()
// 获取全部依赖,有重复 集合 dependenciesConfiguration.getIncoming().getResolutionResult().getAllDependencies()
// 非所有依赖,只有task 所在build.gradle 中的依赖的集合(一级依赖) dependenciesConfiguration.getIncoming().getResolutionResult().getRoot().getDependencies()
|
2.获取aar的本地路径
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| // 构建请求参数 Action<AttributeContainer> attributes = new Action<AttributeContainer>() { @Override void execute(AttributeContainer container) { //key : AndroidArtifacts.MODULE_PATH,AndroidArtifacts.ARTIFACT_TYPE //AndroidArtifacts中type类型 aar,android-classes等,会帮我们过滤 // 配置有疑问 参考 VariantScopeImpl 中 //container.attribute(ARTIFACT_TYPE, "android-classes"); } }
ArtifactCollection compileArtifactCollection = compileClassPathConfiguration.getIncoming() .artifactView(new Action<org.gradle.api.artifacts.ArtifactView.ViewConfiguration>() { @Override void execute(org.gradle.api.artifacts.ArtifactView.ViewConfiguration viewConfiguration) { viewConfiguration.lenient(true) viewConfiguration.attributes(attributes) } }).getArtifacts();
ArtifactCollection runtimeArtifactCollection = runtimeClassPathConfiguration.getIncoming() .artifactView(new Action<org.gradle.api.artifacts.ArtifactView.ViewConfiguration>() { @Override void execute(org.gradle.api.artifacts.ArtifactView.ViewConfiguration viewConfiguration) { viewConfiguration.lenient(true) viewConfiguration.attributes(attributes) } }).getArtifacts();
// 获取路径集合 Set<ResolvedArtifactResult> resolvedArtifactResults = compileArtifactCollection.getArtifacts()
|
比较依赖
1.解压
1 2 3 4 5 6 7 8 9 10 11 12
| def copy(String fromPath, String outPath) { getProject().copy { from(getProject().zipTree(fromPath)) into(outPath) // 判断解压路径outPath中是否有jar包,有的话继续解压 File [] outPathFiles = getProject().file(i).listFiles() for(File child : outPathFiles) { if(child.getName().contains('.jar')) { copy(childFile.getAbsolutePath(), childFile.getAbsolutePath() + "_dir") } } }
|
2.比较
3.输出
输出方式:html,console