一、入职
经历了重重面试,终于入职心仪公司了。我都忘记怎么上班了
领导把Git地址发给你,先看看项目熟悉一下。规范化的公司还会有项目文档、历史需求文档帮助你熟悉。如果没有的话就全靠你自己了。
- 你要Git clone到本地,配好运行环境跑起来。
- 看看有哪些module、分多少层(一般app、common、feature等等)。
- 找入口(AndroidManifest里面的Application、MainActivity等等),开始调试。
- 这个时候可以debug看看初始化过程,自定义一些mock数据跑跑某个单元。
- 找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
闭包来执行目录树打印操作。
使用说明:
- 将上述代码添加到你的
build.gradle
文件中。 - 保存
build.gradle
文件。 - 在终端或命令行工具中,导航到包含
build.gradle
文件的目录。 - 运行以下命令来执行新创建的任务:
./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}")
}
}