Android studio 工程的 module 依赖关系图绘制 、 Android Module 依赖关系的可视化实现

整体步骤:

  • 1、利用gradle脚本生成dot;

  • 2、利用graphviz将dot可视化转为图片

利用gradle脚本生成dot

下载projectDependencyGraph.gradle脚本

下载 projectDependencyGraph.gradle ,放在项目根目录,

源码如下:

task projectDependencyGraph {
    doLast {
        def dot = new File(rootProject.buildDir, 'reports/dependency-graph/project.dot')
        dot.parentFile.mkdirs()
        dot.delete()

        dot << 'digraph {\n'
        dot << "  graph [label=\"${rootProject.name}\\n \",labelloc=t,fontsize=30,ranksep=1.4];\n"
        dot << '  node [style=filled, fillcolor="#bbbbbb"];\n'
        dot << '  rankdir=TB;\n'

        def rootProjects = []
        def queue = [rootProject]
        while (!queue.isEmpty()) {
            def project = queue.remove(0)
            rootProjects.add(project)
            queue.addAll(project.childProjects.values())
        }

        def projects = new LinkedHashSet<Project>()
        def dependencies = new LinkedHashMap<Tuple2<Project, Project>, List<String>>()
        def multiplatformProjects = []
        def jsProjects = []
        def androidProjects = []
        def javaProjects = []

        queue = [rootProject]
        while (!queue.isEmpty()) {
            def project = queue.remove(0)
            queue.addAll(project.childProjects.values())

            if (project.plugins.hasPlugin('org.jetbrains.kotlin.multiplatform')) {
                multiplatformProjects.add(project)
            }
            if (project.plugins.hasPlugin('org.jetbrains.kotlin.js')) {
                jsProjects.add(project)
            }
            if (project.plugins.hasPlugin('com.android.library') || project.plugins.hasPlugin('com.android.application')) {
                androidProjects.add(project)
            }
            if (project.plugins.hasPlugin('java-library') || project.plugins.hasPlugin('java')) {
                javaProjects.add(project)
            }

            project.configurations.all { config ->
                config.dependencies
                        .withType(ProjectDependency)
                        .collect { it.dependencyProject }
                        .each { dependency ->
                            projects.add(project)
                            projects.add(dependency)
                            rootProjects.remove(dependency)

                            def graphKey = new Tuple2<Project, Project>(project, dependency)
                            def traits = dependencies.computeIfAbsent(graphKey) { new ArrayList<String>() }

                            if (config.name.toLowerCase().endsWith('implementation')) {
                                traits.add('style=dotted')
                            }
                        }
            }
        }

        projects = projects.sort { it.path }

        dot << '\n  # Projects\n\n'
        for (project in projects) {
            def traits = []

            if (rootProjects.contains(project)) {
                traits.add('shape=box')
            }

            if (multiplatformProjects.contains(project)) {
                traits.add('fillcolor="#ffd2b3"')
            } else if (jsProjects.contains(project)) {
                traits.add('fillcolor="#ffffba"')
            } else if (androidProjects.contains(project)) {
                traits.add('fillcolor="#baffc9"')
            } else if (javaProjects.contains(project)) {
                traits.add('fillcolor="#ffb3ba"')
            } else {
                traits.add('fillcolor="#eeeeee"')
            }

            dot << "  \"${project.path}\" [${traits.join(", ")}];\n"
        }

        dot << '\n  {rank = same;'
        for (project in projects) {
            if (rootProjects.contains(project)) {
                dot << " \"${project.path}\";"
            }
        }
        dot << '}\n'

        dot << '\n  # Dependencies\n\n'
        dependencies.forEach { key, traits ->
            dot << "  \"${key.first.path}\" -> \"${key.second.path}\""
            if (!traits.isEmpty()) {
                dot << " [${traits.join(", ")}]"
            }
            dot << '\n'
        }

        dot << '}\n'

//        def p = 'dot -Tpng -O project.dot'.execute([], dot.parentFile)
//        p.waitFor()
//        if (p.exitValue() != 0) {
//            throw new RuntimeException(p.errorStream.text)
//        }
//
//        println("Project module dependency graph created at ${dot.absolutePath}.png")
    }
}

引用:

apply from: "${project.rootProject.file('projectDependencyGraph.gradle')}"

运行脚本 :

gradlew projectDependencyGraph

根目录会生成 build\reports\dependency-graph\project.dot

执行完命令后,会生成对应的dot文件
dot 是图形描述语言,简单来说就是用来描述一个图片的

查看

网页打开 .dot在线预览,复制.dot内容进入,即可查看

利用graphviz将dot可视化转为图片

为了把 dot 文件转 png 图片,你的机器上需要安装 GraphvizDownload | Graphviz。这玩意就是把 dot 转 png 的工具。

使用graphviz命令生成图即可,如下:

dot .\pp.dot -T jpg -o 11.jpg

若电脑上已安装Graphviz,可把上面脚本注释部分打开,即可把dot文件直接生成图片。

把上面脚本注释部分打开,电脑上未安装Graphviz,会报错 :

java.io.IOException:
Cannot run program “dot” (in directory “\build\reports\dependency-graph”):
CreateProcess error=2, 系统找不到指定的文件。

下载了Graphviz,命令行输入dot -V,若找不到命令需要配置环境变量。我这里是直接在path中添加bin目录即可。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Android Studio中解决依赖关系错误的方法如下: 1. 检查依赖关系:首先,你需要检查你的项目中的依赖关系。你可以在项目的build.gradle文件中找到这些依赖项。确保所有的依赖项都正确且没有重复。 2. 排除重复依赖项:如果你发现有重复的依赖项,你可以使用exclude关键字来排除其中一个依赖项。例如,如果你的项目中同时引用了两个库A和B,而这两个库都依赖于库C,你可以在build.gradle文件中的相应依赖项中添加exclude关键字来排除其中一个库对库C的依赖。示例代码如下: ```groovy implementation('com.libraryA') { exclude group: 'com.libraryC' } ``` 3. 更新依赖项版本:有时候,依赖项的版本可能过低或过高,导致冲突或错误。你可以尝试更新依赖项的版本来解决问题。在build.gradle文件中,将相应依赖项的版本号更改为最新版本。示例代码如下: ```groovy implementation 'com.libraryA:1.0.0' // 旧版本 implementation 'com.libraryA:2.0.0' // 新版本 ``` 4. 清理和重新构建项目:如果上述方法都无效,你可以尝试清理和重新构建你的项目。在Android Studio中,选择菜单栏中的"Build",然后选择"Clean Project"和"Rebuild Project"选项。这将清除所有生成的文件并重新构建项目。 5. 使用依赖冲突解决工具:如果你的项目中存在复杂的依赖关系冲突,你可以使用一些依赖冲突解决工具来帮助你解决问题。例如,可以使用"gradle-dependency-analyze"插件来分析和解决依赖关系冲突。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值