快捷键:把鼠标操作换成键盘
IDE 的效率差距,八成来自快捷键的熟练度。下面这些动作每天会做几十次,值得专门练到肌肉记忆。
- 快速搜索一切:Shift 连按两次,搜类名、文件、动作、设置项,一个入口解决大部分“我要找什么”。
- 查找定义与用法:Ctrl + 点击跳转定义,Ctrl + Alt + B 查实现,Alt + F7 查所有引用。
- 文件与符号内搜索:Ctrl + F 当前文件,Ctrl + Shift + F 全工程,Ctrl + F12 看方法结构。
- 编辑增强:Ctrl + D 复制行,Ctrl + Y 删除行,Alt + Shift + 上下移动整行,Ctrl + Alt + L 格式化。
- 重构:Shift + F6 重命名,Ctrl + Alt + M 提取方法,Ctrl + Alt + V 提取变量。
建议只先练五个最常用的,一周内就能形成习惯。贪多记不住,反而会退回鼠标操作。
实时模板与代码生成
实时模板(Live Templates)用几个字母展开成一段代码,是省时间最直接的方式。Android Studio 内置了不少,也可以自定义。
- logt生成带当前类名 TAG 的日志语句,配合过滤标签快速定位。
- toast生成 Toast 调用,写临时提示非常快。
- ifn / inn生成 if (x == null) 与 if (x != null) 判空分支。
- fori / foreach生成索引循环与增强循环,避免手敲括号。
除了输入模板,还要善用“生成”菜单(Alt + Insert):快速生成构造函数、getter/setter、equals/hashCode、重写方法与测试类。这些样板代码手写既慢又容易出错。
重构:安全改名与移动
“全局替换”是最危险的操作之一,它会把注释、字符串和其他无关位置一起改掉。重构功能才是安全的选择,因为它基于语义分析。
- 重命名(Shift + F6):同时更新所有引用(含其他模块与 XML 资源引用),并可预览改动范围。
- 移动(F6):把类从一个包移到另一个包,自动修正 import。
- 提取方法 / 变量 / 参数(Ctrl + Alt + M / V / P):把长函数拆开,是改善可读性最常用的一招。
- 内联(Ctrl + Alt + N):把多余的中间变量与包装函数去掉。
- 改变签名(Ctrl + F6):增删参数、调整顺序,一次性更新所有调用点。
良好的习惯是:每次重构后立刻跑一次单元测试或编译。小步快跑,出问题时改动范围小、回退成本低。
调试器:断点、条件断点与变量求值
调试器远比 print 日志强大,尤其是条件断点与变量求值这两个功能,能省下大量重复运行的时间。
- 条件断点:右键断点设置条件(如 userId == "1024"),只在满足条件时暂停,避免在一万次循环里点一万次继续。
- 日志断点:不暂停,只打印表达式,相当于不用改代码的动态日志。
- 求值表达式:暂停时可直接对任意表达式求值,验证你的假设而不用重新编译。
- 异常断点:在抛出指定异常时自动暂停,用于定位偶发崩溃的源头。
- 变量观察:把关键对象加入 Watches,单步执行时随时查看其状态变化。
附件进程调试时,记得在 build.gradle 里开启 debuggable,否则断点不会生效。这一步经常被忽略,导致反复怀疑 IDE。
调试完的逻辑值得固化成单元测试:在 IDE 里点方法名旁的绿色箭头就能直接跑,之后每次改动都会自动回归。下面这个测试针对“手机号脱敏”与“协程状态流”,覆盖了断言、异常与异步等待三个常用场景:
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.test.runTest
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Test
class PhoneFormatTest {
// 同步逻辑:普通断言即可
@Test
fun `11 位手机号应脱敏为 3+4 星号`() {
assertEquals("138****8000", maskPhone("13800138000"))
}
@Test
fun `非法长度原样返回`() {
assertEquals("123", maskPhone("123"))
assertTrue(maskPhone("").isEmpty())
}
// 异步逻辑:用 runTest 等待状态流,避免虚拟时间导致测试变慢
@Test
fun `加载成功后状态应变为 Loaded`() = runTest {
val vm = UserViewModel(repo = FakeRepo())
vm.load("u_1")
val state = vm.state.first { it !is Loading } // 等到第一个非 Loading 状态
assertTrue(state is Loaded)
assertEquals("绿码", (state as Loaded).user.name)
}
}
注意最后一段使用了 runTest 与 first { } 的组合:前者让挂起函数在测试线程里同步推进,后者避免读取到中间态。这样写出的测试既稳定又快,不会因为真实网络或延迟而随机失败。
分析器:CPU、内存与网络
Android Studio 内置的 Profiler 覆盖了性能排查的三大方向,用熟之后定位问题会快很多。
| 方向 | 能回答的问题 | 典型用法 |
|---|---|---|
| CPU | 谁在占用主线程? | 录制一段操作,看调用火焰图里最宽的块 |
| 内存 | 对象为什么越来越多? | 抓堆快照,按类名排序找泄漏增长点 |
| 网络 | 请求为什么慢? | 看单个请求的时间线与响应体大小 |
| 能耗 | 后台为什么耗电? | 关联定位、网络与唤醒锁的使用情况 |
使用建议:录制时间控制在 10 到 20 秒,且只做一件明确的事(如“冷启动到首页可见”)。录制太长、操作太多,火焰图会变成一团糊,什么都看不出来。
版本控制与 Git 集成
IDE 内置的 Git 集成能做到“几乎不切命令行”,但前提是理解几个关键视图。
- Annotate(右键行号区域):逐行显示最后修改者与提交信息,排查“这行谁改的、为什么改”非常高效。
- Local Changes / Commit 面板:分块暂存(chunk),把不相关的改动分开提交。
- 冲突解决:三方合并视图,确认左右差异后再接受,不要盲目点“全部接受”。
- Shelve / Stash:临时切换分支时保存当前改动。
# 命令行里同样常用的三组操作
git log --oneline -20 # 最近 20 条提交
git diff --stat HEAD~1 # 上次提交改了哪些文件
git stash push -m "临时保存:改样式" # 带说明的暂存,避免日后忘记内容
提交习惯上坚持两点:一次提交只做一件事;提交信息写清“为什么改”而不是“改了什么”——后者从 diff 就能看出来。
插件与配置同步
插件能补足 IDE 的能力,但也要克制:装太多会拖慢启动、增加冲突。一年下来真正值得装的通常不超过五个。
- 代码检查与静态分析类插件:在编译前发现潜在 bug 与坏味道。
- JSON / YAML / 数据库工具类插件:编辑配置文件与连接数据库时省事。
- 主题与图标类插件:纯观感提升,按个人喜好选择即可。
更值得花时间的是配置同步:用 IDE 自带的设置同步功能,或把 codeStyle、inspection 规则提交到仓库,让团队所有人的格式化与检查规则一致。这样每次提交都不会混入大量格式差异,代码评审才能真正聚焦在逻辑上。
另外记得配置统一的 JDK 与 Gradle JDK 版本,并把 .idea 中与个人环境相关的文件加入忽略列表。
把效率固化成工作流
单个技巧的提升有限,把技巧串成固定流程才有复利。一个可参考的日常节奏是:
- 接到需求后先用 Shift 连按两次搜索相关类,确认改动范围。
- 写代码时用模板生成骨架,用重命名与提取方法保持结构清晰。
- 功能完成后先写一个单元测试验证核心逻辑,再上真机看交互。
- 提交前格式化并把无关改动分块拆开,写清提交信息。
- 每周花十分钟整理常用模板与忽略规则,让环境越来越顺手。
效率工具的价值不在装了多少,而在你能不能在无意识状态下用出来。刻意练习一两周,收益会持续几年。
下一步建议读《Gradle 构建优化》,把每天等待编译的时间也压下来——那通常是开发流程中最大的一块隐形损耗。