Android开发技巧
Android Studio开发技巧
IDEA通用基础快捷键
不用全部背,记住一些自己经常会用到的即可。
这些快捷键不一定全都会用上,毕竟快捷键只是为了方便图形化界面的功能使用产生的(甚至有的快捷键比图形化界面用起来还麻烦)
文件/目录快捷操作
文本编码
代码补全与导航
代码编辑
代码块折叠与展开
查找与替换
调试
版本控制
快捷重构
快捷导航
快捷Git操作
其他
开发辅助技巧
上面的快捷键太多了,没必要记,这里来说几个比较实用的快捷键。
shift+shift
会弹出一个窗口,我们可以搜索整个项目的文件(按文件名查找):

Ctrl+F
在当前文件中搜索字符:

右边的分别是显示上一个(下一个)匹配结果,然后用筛选条件来匹配,下拉栏里第一个是底部弹出一个窗口,展示所有匹配结果的位置(在哪个类哪个函数)。
Ctrl+Shift+F
全局搜索字符(注意和文件名搜索分开,注意可能与输入法简繁体切换冲突)

从左往右依次是在整个项目查找、在某个模块查找、在某个目录下查找、在某个作用域里查找。
其他
Ctrl+P:显示函数参数
Ctrl+e:显示最近使用的文件
Ctrl+←→ 快速移动光标,可以跨越单词地移动光标
Ctrl+Alt+←→,可以快速查看上次访问的地方(翻阅源码时很常用)
Shift+F6 refactor 重命名
Ctrl+Alt+L 格式化代码 (很常用)
Ctrl+W 扩展选择范围,选择单词继而语句继而函数
Ctrl+Shift+W 缩小选择选择范围,选择函数继而语句继而单词
Ctrl+A 全选
Shift+R 全局替换内容,可以用于搜索,手动重命名
Ctrl+Alt+B 查找方法引用和声明(跟 Ctrl+ 点击函数一样效果)
Ctrl+U 找到父类方法(很常用)
Ctrl+Alt+Shift+T 打开 refactor 菜单
Ctrl+Alt+F 局部变量快速变为全局变量
Debug
老传统了,from 郭神的图:

其他
使用 TODO 注释,会自动标记,可以在这里查看 TODO

日志筛选 LogCat:

代码的类型推断提示设置

文档注释
总所周知,注释是给人看的,但是现代的部分编程语言,其编译器和支持其的 IDE 是可以读懂文档注释的 (这里我们不进行进一步的讨论,仅展示下用法) 在方法或函数上写出如下格式的文档注释(Java 和 Kotlin 通用)

然后在使用时就能看到:

show kotlin ByteCode是将 Kotlin 代码编译为字节码,然后将字节码翻译为 java 伪代码,在学习 kotlin 语法原理和实现细节时很有用。


Git
git 的基础概念以及简单的使用在上学期讲过,有遗忘的可以回去看一下这篇文档:Git&Github。
前置概念引入
分支(branch)
在 git 中,分支指的是从主线上分离出来进行另外的操作,既不影响主线,主线又可以继续干它的事,它可用来解决临时需求;当分支做完事后可合并到主线上,而分支的任务完成可以删掉了。
每个分支被创建时实际上可以看成 截取当前时间节点的主线 ( 就是主分支的意思,一般约定俗成的名称为main分支 , 当然也可以用其他的名称 )。创建一个副本分支 ( 类似于平行世界) ,当“平行世界”的使命完成时就可以与“主世界”相融合,这样在“平行世界”发生的事就会在“主世界”成为既定的现实。
每一个分支相当于一个与主分支隔离的环境,我们可以在其中进行如下操作:
新功能的开发
bug 的修复
提交(commit)
commit 从实际意义上就相当于是我们 基于当前分支对代码的修改记录 ,逻辑上可以类比为 RPG 游戏的存档点
这里提一下 HEAD , 它是一个特殊的引用,默认只会指向当前分支的最新的 commit(当然也可强制改变 HEAD 的指向,它其实就是一个指针)
分支的细节逻辑
结合上面提到的概念,稍微讲一下 git 分支的细节逻辑:
当 git 需要创建新分支的时候,它不需要将主分支的所有内容重新拷贝一份副本,只需要让新分支的 指针指向某一个 commit 对象,这个 commit 对象及其之前的所有 commit 内容都将作为新分支的基础。然后对新分支进行修改再提交之后,那么新分支的指针就会指向你对新分支最新提交的这个 commit 对象,而原来分支的指针则指向你原来开发的位置 (不会因为新分支的建立而收到影响) 而当你在哪个分支开发,HEAD 就指向那个分支的最新提交对象 commit。
上述逻辑流程的 关键点 在于 git 将代码的修改与原本的文件进行分离存储,而不是将修改直接覆盖到源文件.
配合
git branch与流程图来生动形象一下
我们可以用命令 git branch 来查看我们的 git 仓库有几个分支,而名字前面有个 * 号的就为我们目前所处的工作分支。

我们可以通过命令git branch <branch_name>来创建新分支,而这个分支的指针就指向该分支最新的 commit 对象,也就和 HEAD 指向同一对象。我们可以通过命令 git checkout<branch_name> 来切换到目的分支,我们默认的主分支为 main

分支的创建和切换,其实只是简单的创建指针找指针而已,而根据找到的指针找到所指向的 commit 对象,然后将工作空间恢复成该 commit 对象所指的文件快照让我们来工作。当提交一次,指针就重新指向这个最新提交的对象,特别的简单。
比如我们在创建新的分支前:

此时只有一个 main 分支,同时HEAD指向最新的 commit 也就是 commit_3。
此时如果我们创建一个 dev 分支,dev 也指向 commit_3:
而且此时也没有切换当前的分支,故 HEAD 不改变当我们在 dev 分支上开发并提交了两个版本 commit_4 , commit_5 后,由于 HEAD 要指向最新的 commit,因此会指向 dev 分支的最新 commit:commit_5(如下图):

假如这时候 dev 开发完成,要和 main 分支合并,由于 main 没有另外迁出版本 **(用树来形容就是,树的主干自新枝桠长出的那一刻直到现在为止都停止了生长,而且没有生出另外的新的枝桠)**,与 dev 不冲突,那么就会直接将 main 指针指向最新版本 commit_5,也就是 Fast-forward 合并,此时如果 dev 分支任务完成了,删除 dev 分支即可:

如果在 dev 开发两个版本后,在 main 分支的版本也更新了 commit_6 , commit_7 的话,首先 HEAD 会指向最新一次 commit,也就是 commit_7:

此时要将 dev 合并进 main 分支,需要将 commit_5 和 commit_7 合并成一个 commit_8 版本,如果 commit_5 和 commit_7 的文件差别较大,需要手动处理好两个版本间的冲突才能继续合并:

本地分支、追踪分支和远程分支
本地分支:本地分支就是我们可以通过 git branch 查看到的分支,也就是我们自己 git 仓库所拥有的分支,我们都可以利用。
远程分支:远程分支是对远程仓库的分支的索引(有着一一对应关系),它其实也是本地分支,只是我们无法移动它,必须要在和中心服务器交互根据服务器更新到本地来的代码移动的,远程分支的作用就是我们上次和中心服务器交互更新得到的最新版本,它也是个指针。
追踪分支:追踪分支比较难理解,它也是一个本地分支,只是它对应了一个远程分支,如果我们本地的某个分支对应了一个特定的远程分支(名称可以不同),而且两分支的进度必须相同,那么它才能是追踪分支,比如我们最初的 main 分支就是一个追踪分支,它对应远程分支 origin/main,这里 origin 是远程仓库名,当我们在 main 分支里执行更新 (fetch,pull) 或是推送(push),在不显示指定分支参数的情况下,默认就是从 origin/main 分支更新来或者提交到 origin/main 分支。
比如说,我刚从远程拉下来一个仓库:

此时, HEAD 指向最新一次 commit 版本 commit_3,本地分支 main 也指向 commit_3,远程分支 origin/main 也指向 commit_3。 这里本地的 main 分支对应了远程的 origin/main 分支,因此此时的 main 分支就可以被称为追踪分支。
如果我们没有及时更新远程分支,自己在本地埋头苦干更新本地版本的话,就会是这样的情况:

当我们在本地开发的时候,已经有人开发完成并且推送到远程分支的话 (也就是远程分支在未与本地分支同步的情况下,被团队里的其他成员更行了),可怕的事情就来了:

当我们把远程分支更新到本地之后一看,好家伙,别人都把远程推到 commit_8 了,如果要把我们本地的合并进最新的远程分支,又要处理一堆的冲突。因此建议大家在多人开发的时候一定要及时拉取最新的分支。
常用命令
add操作
git add . //将所有“没被忽略”的文件的修改添加到暂存区(有些文件被.gitignore过滤,一般来说会过滤掉build文件来减小GitHub上仓库的体积)
git add * //添加所有的文件,包括(被.gitignore忽略的)当一个文件被 add 了,他的修改自始至终都会被 git 追踪(tracked),包括删除
当一个文件没有被 add,git 中的各种操作将对他毫无影响(untracked)
当你准备提交一部分文件作为新的 commit 时,一般会在 commit 前进行 add 操作对吧,这里的 add 只是标注“哪些文件的修改需要添加到这次 commit 中”。而不是“将“将哪些文件添加到这次 commit”。(为了强调上面这部分,实际上是因为,网上很多教程说 add 命令就是把“文件”添加到暂存区,这导致我们以为没有 add 的文件就不在本次提交的范围内,以后回退也不受影响。其实没 add 的文件只是没提交修改罢了,git 提交这些文件的时候只是忽略了你本次的修改)
rm操作
git rm [文件名] //会删除暂存区或者分支上的文件,工作区的文件也会被删除(相当于rm后再git add)
git rm --cached //是从git取消对本文件的追踪(不会删除工作区文件)。当你不想对本文件进行版本控制了,就用本命令commit操作
将暂存区的内容合并为一个 commit 保存到本地版本库里
git commit -m "[提交的描述信息]" // 直接提交信息
git commit -a -m "[提交的描述信息]" //相当于执行git commit -m 前先执行git add .
git commit //会弹出一个vim编辑器(linux的一个文本编辑器),输入一些commit文本后退出就行。这个git commit命令实际上和git commit -m 命令是等效的。branch操作
git branch [名称] //新建一个分支
git branch -r //列出远程分支
git branch //列出本地分支,并且在当前分支前面加*号
git branch -a //列出所有分支,包括远程分支,并且在当前分支前面加*号
git branch -d [名称] //删除本地分支
git branch -d -r [名称] //删除远程分支
git branch -m [旧名称] [新名称] //分支重命名
git branch -vv //查看本地仓库和远程仓库的对应关系log操作
git log //查看
loggit log --graph //使用图形化的样子查看
loggit log -p //会显示每次提交的差异细节
git log --stat //显示每次提交的统计信息(行数变化,修改过哪些文件)
git reflog //查看引用的历史,默认为HEADdiff操作
git diff [文件名] // 显示工作区和暂存区文件的差异,如果没有add过(暂存区没有它),则对比的是最近一次版本和工作区的差异。
git diff [分支名] [文件名] // 对比工作区的文件和分支的文件的差别
git diff --cached [文件名] // 对比暂存区和git仓库的区别(就是暂存区和最近一次commit的差异)
git diff [哈希码] [文件名] // 对比工作区和git仓库中某次提交的区别
git diff --cached [哈希码] [文件名] // 对比暂存区和git仓库中某次提交的区别
git diff [哈希码] [哈希码] // 对比任意两次提交(可以来自不同分支呀,因为每次提交都有唯一的哈希码)clone操作
先克隆引用,然后根据引用的指向依次拿到 commit 对象,一直拿到溯源拿到根部的 commit
push操作
将本地仓库的保存的 commit 等推到远程仓库
先将 HEAD 及指向的推到远程,然后把分支指向的 commit 补全,然后远端的 HEAD 会更新指到分支头上,同时本地的远端镜像也会更新
git remote //查看现有的仓库有哪些(一般只有一个origin仓库,这是默认的名称)
git remote -v //可以查看仓库的地址git push [远程主机名/仓库名] [本地分支名]:[远程分支名] //会将某个分支推送到远程分支上
git push [远程主机名/仓库名] //表示将当前分支推送到[远程主机名]的对应分支。
git push -f //强行推送,慎用,不清楚具体逻辑就不要用它git push 如果只有一个主机则 [远程主机名] 可以省略,如果有多个远程主机,则需要 git push -uorigin main 先上传一次,这样会将本地的 main 分支推送到 origin 主机,同时指定 origin 为默认主机,后面就可以不加任何参数使用 git push 了。这里的 -u 就是 --set-upstream
pull操作
git pull //相当于两个指令操作(fetch后再merge)
git fetch
git merge origin/?git fetch 会把所有的最新远端镜像更新到本地,然后更新缺少的 commit,相当于是同步
git merge 会合并当前 HEAD 指向的分支,其余分支并不会
merge操作
git merge [分支名]
参数 --commit(默认)自动生成一个提交,包含两个节点合并的结果。
参数 --no-commit 为了防止合并失败,先不提交,让用户手动提交
将当前分支向 [分支名] 合并,并生成一个合并后的 commit
如果有冲突则要先 fix conflicts,git 会列出冲突的文件,我们需要打开这些文件一个一个地合并(git 自动合并了全部,我们只用删掉不需要的部分即可),然后重新 commit 就行了(这时不用再 merge 了)
远端仓库不同的情况
现在假设两个人在对同一个项目做开发,但是我们两个的分支却各不相同,在远端也不相同:

那么为了保证这种操作的安全性,我们应该在合并之前,先切到主要的分支,然后 pull 主要分支,为了是保证本地的主要分支和远端相同。
git checkout main // 本地切换到 main分支
git pull origin main
然后现在可以把自己开发的 feature 分支,merge 进 main
git merge feature // 我当前在本地的main分支,然后要将featrue分支合并到main分支
现在就可以 push 上去,让远端与本地相同
然后对于另一个人来说,这也是一个同样的步骤现在仔细想一想,你的 feature 分支有被提交到远端吗,其实是并没有的,因为之前我们 push 的地方是讲过的,只会 push 当前的分支。
当然会有一种极端的情况,你刚刚拉下来,正在 merge,然后另一个人又写完了,又推到远端分支了,那么这个时候,你必须重新从远端拉下来,重新 merge 后再推上去。
那么,分支的主要作用是什么呢,是为了区分不同的项目,比如说 3 个项目同时进行,那么应该是有三个分支,最后写完了再 merge,当在写的过程中,如果突然加了新的需求,那么应该在 3 个分支分开的地方开始新的第四个分支,确保分支的准确。
还有一种合并的方式,是在远端合并,名叫 pull request(PR,掌邮的 github 源码当前使用的就是这个合并方式)可以将远端的两个分支进行 merge,当然这种 merge,其实是:
git merge feature --no-ff他会留下一个 merge 的信息,留来做更多的分析当然,这种合并是不能有冲突的,如果有冲突,是不让你合并的所以说一般改小 bug,可以直接 pr 合并,如果是大的合并,需要在本地进行合并后推到远端。
checkout操作
checkout 会将 HEAD 指针指向分支或者指向某一个 commit
如果要指向自己的分支所在的 commit,那么需要使用 --detach
可以使用 git log ,然后指向 hash 码值:
git checkout [名称] //切换分支
git checkout -b [名称] //新建一个分支并切换到该分支上
git checkout -q [名称] //无提示切换分支
git checkout -f [名称] //强制切换(如果工作区有修改,则丢弃本次修改,强制切换到分支)rebase操作
顾名思义,变基,即改变当前分支指向的基础
假设有这样一条本地分支树 (当前在 featrue 分支):

执行 git rebase main 之后:

使用 rebase 可以简化美化分支,也是合并操作,但是他会将分支复制一份,然后只显示从 1-4‘这一条线路 (美化分支路径),同时如果 4 还有分支指向的话,不会随着 feature 一起移动
使用 rebase -i 可以使用交互式的提交修改,可以使用其他指令来修改这个 rebase 过程
reset操作
这个也是一个比较常用的操作,可以带着分支一起往某个 commit 移动,或者将当前分支移动到某个分支所指向的 commit
如果使用 reset,只会更改 git 部分,实际的文件是不会改变的
那么需要使用:
git reset --hard [哈希值]改错操作
使用 git commit --amend
来修改刚才的最新提交,虽然说是看起来新增了一个新提交,但是其实是克隆了一个新的提交,和 rebase 同理
如果已经 push 到远端了该怎么办?
使用 git revert 就是反向操作,把做过的操作返向,他是新增了一个反向的 commit,并不是删减,而是增加一个负的 commit 来抵消代码
如果发现自己的代码一次性写太多了,然后没有 commit,可以使用 git add -i 去自定义自己的 add(比如把依次 add 的内容分割为多次 commit),然后再 commit 这个想了解的话自己去查一下,因为使用频率很少
tag操作
在完成发版之前的所有改动之后,修改版本号,并 commit 一个 [release] 信息
然后进行 release tag 操作
比如:
git tag -a v6.3.2-71 -m '紧急热修复测试后版本更改'即在本地打出下面格式的命令来编辑并提交 tag:
git tag -a [版本号] -m '版本信息给过去的 commit 打 tag:
git tag -a [tag名称] [commit的hash值] -m '信息'通过命令同步上去 :
git push origin --tags 全部推送
git push origin tag名称 推送指定名称那个 tag
如果突然发现有严重 bug,可以删除本地 tag(注意此时也是删除的本地,还需要 push 一下)
git tag -d 版本号删除远程的 tag:
git push origin:refs/tags/v6.3.2-71可以使用 tag 来代替具体 commit 记录:
git checkout tag名称
git checkout -b new分支名称 tag名称
git pull --t tag名称github 仓库中也可以查看 tag 记录,可以不同的 tag 选择创建对应 release 版本,方便后续管理和公示版本
cherry-pick操作
对于多分支的代码库,将代码从一个分支转移到另一个分支是常见需求
当需要另一个分支的所有代码变动,那么就采用合并( git merge );
当只需要部分代码变动(某几个提交),这时可以采用 Cherry pick 。
如果某个分支不需要了,但是其中的 3 个 commit 又有需要的东西
git cherry-pick hashcode1 hashcode2 hashcode3上面命令就会将指定的 3 个 hashcode 对应的提交,应用于当前分支。
这会在当前分支产生对应个数的新的提交,当然它们的哈希值和原来的会不一样。
另外如果在操作过程中发生代码冲突,Cherry pick 会停下来,让用户决定如何继续操作,不过之后的操作使用 git 命令行比较麻烦,对新手来讲不太友好,给出一个 git 官方文档的链接供查阅:
Git - git-cherry-pick Documentation (git-scm.com)
stash操作
把当前未被 commit 的修改 (工作区和暂存区的都算) 快照进入堆栈,临时保存,多数情况下的使用场景是写代码写到一半,接到个紧急的需求,需要赶紧去做新需求,那么原来写到一半的代码就可以使用 stash 操作暂时保存:
git stash // 等同于git stash save,能够将所有未提交的修改(工作区和暂存区)快照至堆栈中,用于后续恢复当前工作目录。
git stash list //查看当前stash中的内容
git stash pop //将当前stash中的内容弹出,并应用到当前分支对应的工作目录上。相当于回退
git stash apply [stash名字] //将堆栈中的内容应用到当前目录 如:git stash applystash@{1}
git stash drop [stash名字]
git stash clear //清空stash列表
git stash show //查看堆栈中最新保存的stash和当前目录的差异AS的图形化Git操作
这里就不多赘述了,上学期的 git 教程中也简单提到过图形化操作,然后图形化操作在之前郭神写的一篇Android 开发技巧里面有一篇详细的Git 图形化教程,可以自己看一下,看完这个 AS 的图形化操作就没啥问题了,上课也会再带着看一下。
Markdown使用
Markdown编辑软件安装
推荐 Typora , 写起来比较简单,而且所见即所得,缺点是不能同时查看渲染效果页面与源码文本页面
也可以使用VScode+MarkDown插件包代替,优点是能同时查看渲染效果页面与源码文本页面,缺点是需要自己写源码文本,写作效率没有上面的 Typora 高,然后现在还有些 obisidan 啥的,可以自己了解然后选择个最适合自己的软件。
至于怎么安装,请自行通过搜索引擎查找解决方案
使用Typora快速编写md文档
Typora 官方网站:https://www.typora.io
可以找博客或者到官网学习写法,下面就介绍简单的一些语法
标题
使用 Ctrl 与 + 提升标题等级(把标题变大,或者将正文格式变成标题)
使用 Ctrl 与 - 降低标题等级(把标题变小,或者将标题格式变成正文)
这是一级标题
这是二级标题
这是三级标题
这是四级标题
这是五级标题
这是六级标题
这是正文格式
代码如下:
# 这是一级标题
## 这是二级标题
### 这是三级标题
#### 这是四级标题
##### 这是五级标题
###### 这是六级标题可以发现,有几个 #就是几级标题,所以我们就可以敲几个# 然后按空格就能实现对应的标题了。
文字格式
删除线(不是很常用)
语法:~~(波浪线)文字~~(波浪线)
快捷键:Alt + Shift + 5这是删除线
斜体
语法:*文字* 或 _文字_
快捷键:Ctrl + i这是斜体
加粗
语法:**文字** ____文字____
快捷键:Ctrl + B这是加粗
下划线
语法:<u>文字</u>
快捷键:Ctrl + u这是下划线
高亮
语法:==文字==
快捷键:无这是高亮
引用
语法: > 快捷键: Ctrl+Shift+Q
这是引用
表格
快捷键:Ctrl+T
无序列表
快捷键:Ctrl+Shift+]
源码:
* 有三种标记
- 三种标记功能都一样
+ 都是无序列表有三种标记
三种标记功能都一样
都是无序列表
有序列表
快捷键:Ctrl+Shift+[
源码:
1. 数字加.是有序列表
2. 数字的顺序不决定列表的顺序
3. 推荐1 2 3 4 的顺序数字加. 是有序列表
数字的顺序不决定列表的顺序
推荐 1 2 3 4 的顺序
代码块
两种方式,一种是使用 "`"(引号中引用的符号)来包裹内容或代码,另一种是 Ctrl + Shift + K 创建代码块(或者 ```+ 语言),可在其中跳入想写的代码或者其他内容
引号中引用的符号
Ctrl + Shift + K 创建代码块
其源码为:```代码块的语言类型```链接
可跳转链接:
[链接的文字](链接网址)图片链接:
Typora快捷键
无序列表:- + 空格
有序列表:1. + 空格
引用:> + 空格
标题:ctrl + 数字
表格:ctrl + t
生成目录:[TOC] + 回车
选中一整行:ctrl + l
选中单词:ctrl + d
选中相同格式的文字:ctrl + e
跳转到文章开头:ctrl + home
跳转到文章结尾:ctrl + end
搜索:ctrl + f
替换:ctrl + h
加粗:ctrl + b
倾斜:ctrl + i
下划线:ctrl + u
删除线:alt + shift + 5
插入图片:直接拖动到指定位置即可或者 ctrl + shift + i
插入链接:ctrl + k
