新入职如何快速熟悉项目架构

一、入职

经历了重重面试,终于入职心仪公司了。我都忘记怎么上班了

领导把Git地址发给你,先看看项目熟悉一下。规范化的公司还会有项目文档、历史需求文档帮助你熟悉。如果没有的话就全靠你自己了。

  1. 你要Git clone到本地,配好运行环境跑起来。
  2. 看看有哪些module、分多少层(一般app、common、feature等等)。
  3. 找入口(AndroidManifest里面的Application、MainActivity等等),开始调试。
  4. 这个时候可以debug看看初始化过程,自定义一些mock数据跑跑某个单元。
  5. 找leader分配几个Bug给你玩一下,既显得你很积极主动,也能帮助你带着问题去了解项目。搞不定也没关系,自己姿态放低点,问问同事,大部分还是很乐意给你解答的,百度能解决的问题除外。

二、自定义Gradle脚本实现tree结构打印

抛个问题:为什么不直接用tree呢?

原因是Windows的tree指令没有Linux那么好用好看,而且没法过滤某些文件夹比如build等。自己写个脚本,什么环境都能跑,方便的很。所以,搞起来。

在Gradle脚本中定义方法时,需要确保它们被放在适当的位置。通常,你可以在build.gradle文件的顶层或者一个单独的脚本块中定义方法。对于这个问题,我们可以将方法定义放在build.gradle文件的顶层,并在任务中调用它。

代码示例

// 在build.gradle文件的顶层定义方法
def printDirectoryTree(File dir, int level, boolean isLast) {
    
    
    // 打印当前级别的缩进
    String prefix = (level > 0 ? "│   " * (level - 1) : "") + (isLast ? "└── " : "├── ")
    println(prefix + dir.name)

    if (dir.isDirectory()) {
    
    
        File[] files = dir.listFiles()
        if (files != null) {
    
    
            for (int i = 0; i < files.length; i++) {
    
    
                File file = files[i]
                boolean last = (i == files.length - 1)
                if (shouldInclude(file)) {
    
    
                    if (file.isDirectory()) {
    
    
                        printDirectoryTree(file, level + 1, last)
                    }
                }
            }
        }
    }
}

// 定义过滤逻辑
def shouldInclude(File file) {
    
    
    // 这里列出你想要排除的目录或文件
    def excludedDirs = [
            'build',
            'src/main/res',
            '.gradle',
            '.idea',
            'app/build',
            'app/src/main/res',
            'app/src/androidTest',
            'app/src/test',
            '.git'
    ]

    // 获取文件的相对路径
    def relativePath = file.absolutePath.replace(project.rootProject.projectDir.absolutePath, '').replace('\\', '/')

    // 检查是否在排除列表中
    for (String excludedDir : excludedDirs) {
    
    
        if (relativePath.startsWith("/" + excludedDir) || relativePath.contains("/" + excludedDir + "/")) {
    
    
            return false
        }
    }

    return true
}

// 定义tree任务
task tree {
    
    
    doLast {
    
    
        def projectDir = project.rootProject.projectDir
        printDirectoryTree(projectDir, 0, true)
    }
}

解释

  • 方法定义printDirectoryTree方法现在位于build.gradle文件的顶层,这样Gradle可以识别它。
  • 任务定义tree任务仍然使用doLast闭包来执行目录树打印操作。

使用说明

  1. 将上述代码添加到你的build.gradle文件中。
  2. 保存build.gradle文件。
  3. 在终端或命令行工具中,导航到包含build.gradle文件的目录。
  4. 运行以下命令来执行新创建的任务:
    ./gradlew tree
    

这将会输出项目的目录结构,类似于tree命令的结果。

三、打印结果

项目来自:https://github.com/OCNYang/Android-Animation-Set

执行上述任务后,将输出项目的目录结构,但只包含文件夹,过滤掉了指定的文件和目录。

> Task :app:tree
└── Android-Animation-Set
├── app
│   └── src
│   │   ├── main
│   │   │   ├── java
│   │   │   │   └── com
│   │   │   │   │   └── ocnyang
│   │   │   │   │   │   └── androidanimationset
│   │   │   │   │   │   │   └── view
├── constraint-animation
│   └── src
│   │   ├── androidTest
│   │   │   └── java
│   │   │   │   └── com
│   │   │   │   │   └── ocnyang
│   │   │   │   │   │   └── constraint_animation
│   │   ├── main
│   │   │   └── res
│   │   └── test
│   │   │   └── java
│   │   │   │   └── com
│   │   │   │   │   └── ocnyang
│   │   │   │   │   │   └── constraint_animation
├── drawable-animation
│   └── src
│   │   ├── androidTest
│   │   │   └── java
│   │   │   │   └── com
│   │   │   │   │   └── ocnyang
│   │   │   │   │   │   └── drawableanimation
│   │   ├── main
│   │   │   ├── java
│   │   │   │   └── com
│   │   │   │   │   └── ocnyang
│   │   │   │   │   │   └── drawableanimation
│   │   │   └── res
│   │   └── test
│   │   │   └── java
│   │   │   │   └── com
│   │   │   │   │   └── ocnyang
│   │   │   │   │   │   └── drawableanimation
├── gradle
│   └── wrapper
├── property-animation
│   ├── src
│   │   ├── androidTest
│   │   │   └── java
│   │   │   │   └── com
│   │   │   │   │   └── ocnyang
│   │   │   │   │   │   └── propertyanimation
│   │   ├── main
│   │   │   ├── java
│   │   │   │   └── com
│   │   │   │   │   └── ocnyang
│   │   │   │   │   │   └── propertyanimation
│   │   │   └── res
│   │   └── test
│   │   │   └── java
│   │   │   │   └── com
│   │   │   │   │   └── ocnyang
│   │   │   │   │   │   └── propertyanimation
├── README_Res
├── reveal-animation
│   └── src
│   │   ├── androidTest
│   │   │   └── java
│   │   │   │   └── com
│   │   │   │   │   └── ocnyang
│   │   │   │   │   │   └── revealanimation
│   │   ├── main
│   │   │   ├── java
│   │   │   │   └── com
│   │   │   │   │   └── ocnyang
│   │   │   │   │   │   └── revealanimation
│   │   │   └── res
│   │   └── test
│   │   │   └── java
│   │   │   │   └── com
│   │   │   │   │   └── ocnyang
│   │   │   │   │   │   └── revealanimation
├── ripple-animation
│   └── src
│   │   ├── androidTest
│   │   │   └── java
│   │   │   │   └── com
│   │   │   │   │   └── ocnyang
│   │   │   │   │   │   └── rippleanimation
│   │   ├── main
│   │   │   ├── java
│   │   │   │   └── com
│   │   │   │   │   └── ocnyang
│   │   │   │   │   │   └── rippleanimation
│   │   │   └── res
│   │   └── test
│   │   │   └── java
│   │   │   │   └── com
│   │   │   │   │   └── ocnyang
│   │   │   │   │   │   └── rippleanimation
├── state-animation
│   └── src
│   │   ├── androidTest
│   │   │   └── java
│   │   │   │   └── com
│   │   │   │   │   └── ocnyang
│   │   │   │   │   │   └── stateanimation
│   │   ├── main
│   │   │   ├── java
│   │   │   │   └── com
│   │   │   │   │   └── ocnyang
│   │   │   │   │   │   └── stateanimation
│   │   │   └── res
│   │   └── test
│   │   │   └── java
│   │   │   │   └── com
│   │   │   │   │   └── ocnyang
│   │   │   │   │   │   └── stateanimation
├── transition-animation
│   └── src
│   │   ├── androidTest
│   │   │   └── java
│   │   │   │   └── com
│   │   │   │   │   └── ocnyang
│   │   │   │   │   │   └── transitionanimation
│   │   ├── main
│   │   │   ├── java
│   │   │   │   └── com
│   │   │   │   │   └── ocnyang
│   │   │   │   │   │   └── transitionanimation
│   │   │   │   │   │   │   ├── helper
│   │   │   └── res
│   │   └── test
│   │   │   └── java
│   │   │   │   └── com
│   │   │   │   │   └── ocnyang
│   │   │   │   │   │   └── transitionanimation
├── vector-animation
│   ├── src
│   │   ├── androidTest
│   │   │   └── java
│   │   │   │   └── com
│   │   │   │   │   └── ocnyang
│   │   │   │   │   │   └── vectoranimation
│   │   ├── main
│   │   │   ├── java
│   │   │   │   └── com
│   │   │   │   │   └── ocnyang
│   │   │   │   │   │   └── vectoranimation
│   │   │   └── res
│   │   └── test
│   │   │   └── java
│   │   │   │   └── com
│   │   │   │   │   └── ocnyang
│   │   │   │   │   │   └── vectoranimation
└── view-animation
│   ├── src
│   │   ├── androidTest
│   │   │   └── java
│   │   │   │   └── com
│   │   │   │   │   └── ocnyang
│   │   │   │   │   │   └── viewanimation
│   │   ├── main
│   │   │   ├── java
│   │   │   │   └── com
│   │   │   │   │   └── ocnyang
│   │   │   │   │   │   └── viewanimation
│   │   │   └── res
│   │   └── test
│   │   │   └── java
│   │   │   │   └── com
│   │   │   │   │   └── ocnyang
│   │   │   │   │   │   └── viewanimation

BUILD SUCCESSFUL in 780ms
1 actionable task: 1 executed

Build Analyzer results available
22:57:42: Execution finished 'tree'.

四、保存为文件

task运行结果只是打印出来,进一步存为文件,方便拷贝和查阅。

// 在build.gradle文件的顶层定义方法
def printDirectoryTree(File dir, int level, boolean isLast, BufferedWriter writer) {
    
    
    // 打印当前级别的缩进
    String prefix = (level > 0 ? "│   " * (level - 1) : "") + (isLast ? "└── " : "├── ")
    String line = prefix + dir.name
    println(line)  // 仍然输出到控制台(可选)
    writer.write(line + "\n")  // 写入文件

    if (dir.isDirectory()) {
    
    
        File[] files = dir.listFiles()
        if (files != null) {
    
    
            for (int i = 0; i < files.length; i++) {
    
    
                File file = files[i]
                boolean last = (i == files.length - 1)
                if (shouldInclude(file)) {
    
    
                    if (file.isDirectory()) {
    
    
                        printDirectoryTree(file, level + 1, last, writer)
                    }
                }
            }
        }
    }
}

// 定义过滤逻辑
def shouldInclude(File file) {
    
    
    // 这里列出你想要排除的目录或文件
    def excludedDirs = [
        'build',
        'src/main/res',
        '.gradle',
        '.idea',
        'app/build',
        'app/src/main/res',
        'app/src/androidTest',
        'app/src/test',
        '.git'
    ]

    // 获取文件的相对路径
    def relativePath = file.absolutePath.replace(project.rootProject.projectDir.absolutePath, '').replace('\', '/')

    // 检查是否在排除列表中
    for (String excludedDir : excludedDirs) {
    
    
        if (relativePath.startsWith("/" + excludedDir) || relativePath.contains("/" + excludedDir + "/")) {
    
    
            return false
        }
    }

    return true
}

// 定义tree任务
task tree {
    
    
    doLast {
    
    
        def projectDir = project.rootProject.projectDir
        def outputFile = file("${projectDir}/directory_tree.txt")
        outputFile.withWriter {
    
     BufferedWriter writer ->
            printDirectoryTree(projectDir, 0, true, writer)
        }
        println("Directory tree has been written to ${outputFile.absolutePath}")
    }
}

猜你喜欢

转载自blog.csdn.net/qq_36329049/article/details/143196057