无规矩,不成方圆。
0x00 源文件基础
文件名
源文件以最顶层的类名来命名, 大小写敏感.
比如: LoginActivity.java
MainActivity.java
文件编码
UTF-8
0x01 命名
简洁明了, 但慎用缩写, 除非约定俗定.
尽量使用常用英文单词, 而非中文拼音.
包(package)
包名全部使用小写, 按文件的功能作用来组织不同的包
1 | com.[domain].[appname].activity.account |
类(class)
类名采用 大驼峰法.
- 对于继承自 Android 组件的类来说, 命名应以该组件的名称结尾.
- 模型实体类可直接使用名词或名词组合, 不需在后面添加类似
Model
Entity
等后缀. - 工具类使用
XXXUtil
形式的命名, 辅助帮助类使用XXXHelper
, 管理类使用XXXManager
1 | public class LoginActivity |
接口(interface)
接口采用 大驼峰法.
- 对于一般的接口, 在接口名中添加
Callback
able
ible
等后缀. - 对于自定义的UI控件监听类的接口, 使用类似
OnXXXListener
ClassNameOnXXXListener
等形式来命名.
1 | public interface NetCallback |
方法(methods)
方法采用 小驼峰法.
开头一般为动词或动名词, 不要使用名词. 因为一个方法一般都为一个 动作
或者 操作
.
方法名 | 说明 |
---|---|
initXXX() | 与初始化相关 |
isXXX() checkXXX() | 返回值为 boolean 型的方法 |
getXXX() | 返回某个值 |
handleXXX() | 对数据进行处理 |
saveXXX() | 与数据保存相关 |
resetXXX() | 与数据重置相关 |
clearXXX() removeXXX() | 与数据清除相关 |
… | … |
变量(variables)
变量采用 小驼峰法.
Good | Bad |
---|---|
String url | String URL |
String name | String nameString |
ArrayList<User> users |
ArrayList<User> userArrayList |
在变量中__不要使用__
m
s
等前缀, 比如:private mName // 不要这样做
private List<NoticeInfo> mInfos // 不要这样做
常量(Constants)
常量命名使用大写字母加 _
符的方式. 而且常量开头的单词, 最好应说明其类型或用途.
1 | public static final String CONFIG_WEIXIN_APPID = "abcdefg" |
这里值得一提的是, 在 Activity 间跳转传参时, 人们往往习惯性的在
intent.putExtra()
时直接使用字符串的字面量值去指定其中的name
.
这时, 你更应该在将要跳转到的 Activity 类中将这些name
声明为公有的常量值. 这可以避免一些不必要的 bug 的产生.
1 | Intent intent = new Intent(this, NewsDetailActivity.class); |
UI控件(widgets)
这里的UI控件命名, 指的是其变量命名. 一般的形式为 功能/用途
+ 控件缩写后缀
.
1 | private Button loginBtn; |
名称 | 缩写 | 用例 |
---|---|---|
Button | Btn | loginBtn |
TextView | Tv | nameTv |
EditText | Et | passwordEt |
ImageView | Iv | logoIv |
ImageButton | imageBtn | delImageBtn |
LinearLayout | Ll | navigationBarLl |
RelativeLayout | Rl | bottomMenuRl |
FrameLayout | Fl | photoFl |
… | … | … |
对于一些自定义的UI控件, 或者是类名比较长的UI控件的变量命名, 应该慎用缩写.
因为前者的缩写让一个新手去阅读代码时, 会不知所措. 而后者往往是因为缩写对各人有异.
资源文件(layout/drawable/anim/dimens/colors/strings)
不管是文件名还是资源ID名, 全部采用小写, 以下划线 _
分隔各单词.
- Animation 对应的资源文件, 命名为
anim_xxx
1 | anim_scale_in.xml |
- ListView/GridView Item 对应的资源文件, 命名为
listview_item_xxxx
1 | listview_item_subtitle.xml |
- Activity对应的布局资源文件, 命名为
模块名_类名简称_view
1 | account_login_view.xml |
- Dialog对话框对应的布局文件, 命名为
dialog_描述.xml
1 | dialog_with_scroller_view.xml |
- 用于某布局中的子布局资源文件, 比如通过
include
方式引用的子布局, 命名为content_layout_用途
1 | content_layout_empty_prompt.xml |
- 自定义的
style
名(注意这里指的非文件名), 命名为my_控件名/用途_style_风格名
1 | <style name="my_listview_style_default" parent="@android:style/Widget.ListView"> |
0x02 变量声明
一行只写一个变量声明.
需要时才声明, 并尽快进行初始化.
本节没有其它的了.
0x03 注释
能不写注释时, 尽量不要写(写注释就像交朋友, 宁缺勿滥).
但必要的注释一定要添加, 像公开的API方法, 复杂算法的大体思路等(就像你不太可能独身地过完这一生).
说到写注释, 你应该更关注 方法/变量
的命名. 如果命名适当, 那就没注释什么事了.
以下注释的样式以代码的形式出现, 在进行相应地方的注释撰写时, 格式上参照样例代码的样式.
文件头注释
1 | /** |
方法注释
- public 方法
1 | /** |
另外, 接口 interface 中定义方法很有必要添加注释.
- private 方法
1 | // 初始化View |
注意: 上面的注释其实是多余的!!! 上面的注释其实是多余的!!! 上面的注释其实是多余的!!!
方法名initView
已经明示它的作用. 当方法名都无法说明它的作用时, 你应该先考虑一下换个方法命名, 再决定是否添加注释, 更何况这是一个私有的方法.
- protected 方法
自行掂量掂量吧
常量/变量注释
- 常量
一般来说, 常量都有添加注释的必要, 特殊是全局变量.
1 | /** |
- 变量
变量一般无须添加注释, 而是在命名上见名知义.
但有时当一些变量是作特殊用途时, 此时注释的内容应该是描述它起的作用, 而不是描述变量的字面意思.
1 | private Button loginBtn; // 登陆按钮 (多余的注释, 应该去掉) |
在上面的样例代码中, loginBtn 由其命名已经知道这是一个登陆的 Button, 再添加注释是多余的, 这会加重代码阅读者的负担.
而对于password
与logo
, 在某些情况下添加注释是需要的. 像如果这两个字段是属于模型类User
中的字段, 为它们添加注释可以很明确了解后台返回的各字段含义.
代码块注释
对于代码块的注释说明, 最好是可以用一行文字在块的前面简要描述该块代码起到的作用.
对于复杂的算法, 可以多写几行, 描述算法的大体思路. 当有相应的资源链接时, 最好是在注释中添加上.
当某些代码不再使用到时, 最好的做法是及时删除掉, 而不是注释掉. 时刻保持项目代码的整洁是一样美德.
TODO标释
当某个功能代码待实现, 或者某个方法有 bug, 或是某处的代码待优化时, 你应该添加上 // TODO
标注, 并简单说明还需要做的事情.
1 | private void doSomething() |
简单起见, 在这里我们统一使用 // TODO "the message about should do something"
的标释.
对于调试的过程中, 临时性地注释掉某些代码时, 最好也加上
TODO
标释, 避免调试完后忘记了打开注释而产生一些奇怪的问题.
0x04 括号
当无法保持简单时, 也不要自我制造复杂.
大括号
除了数组的初始化声明外, 对于全部的大括号, 另起一新行, 并且 {
与 }
应对齐显示.
一些空白待实现的方法, 其两个大括号也应独立使用两行. (此时你需要在空白实现中添加上 // TODO
标释)
1 | private int[] a = new int[]{1, 2, 3}; |
对于
if/else
语句, 即使只有一行代码, 也应在外层加上大括号. 因为谁也不知道哪天你要扩充这里.
小括号
在三目运算符 ? :
, 或者是逻辑运算符 && ||
中, 当它们很长或者涉及其它方法调用时, 应该在其外层添加上小括号. 当然, 如果代码逻辑已经简洁到一目了然时, 你也可以不添加.
1 | if ((a && b) || (c && d)) |
很多时候, 使用小括号去限定一组逻辑, 这都是你的本职所在.
我们最好假设没有一个人能记住整个 java 运算符优先级表.
0x05 缩进与间隔
保持层次感与内聚性.
队形很重要.
列限制
在IDE中设置一行的列限制为 130
个字符长度(当然, 这个数字可根据实际情况适当加减. 但强烈建议在团队中各成员采用一致的数值).任何一行如果超出该限制, 必须自动换行.
而以下情况时, 可保持为一行:
- 很长的URL字符串
- 注释中那些可能需要被剪切粘贴到 shell 中的命令行
- 很长的方法声明(若真的出现很长的方法声明, 此时你应该先考虑是否要修改方法的命名)
对于很长的链式调用, 可以不必每次调用时都换一行, 在将要超出列限制长度时换行即可.
若换行时, 方法调用前的.
字符必须跟在方法的新行中.
1 | doAction1().doAction2().doAction() |
缩进
缩进使用 4 个空格. 不要使用 tab 字符进行缩进. 可以在 IDE 中设置 tab 键为 4 个空格.
另外: 对于自行换行时, 新行至少要缩放 8
个空格.
缩进样例:
1 | public class Foo |
对于XML资源的缩进
XML里的元素内没有其他元素时, 应该使用自结束的标签
1 | <TextView |
下面是一个不规范的样例:
1 | <!-- 不要这样做 --> |
空格
此处的空格为行代码空格, 指的是一行代码中的各组成元素之间的空格.
包含 变量/常量名
与 关键字
, 参数列表
, 运算符
, 括号
, 逗句
等等元素.
1 | "value1", param2 = "value2") (param1 = |
空白行
- 类/接口/方法之间相互空两行 2
- 相关的变量声明之间不空行 0
- 不相关的变量声明之间空一行 1
- 类/接口内的前后不空行 0
- 方法体内的前后不空行 0
- 在一个方法体内, 联系不紧密的逻辑之间空一行 0
- 可适当的在 return 语句前空一行 0/1
- 在XML布局文件中, 控件之间的声明空一行 1.
但父控件的结束标签与最后的子控件之间不用空行
1 | package com.intellij.samples; |
1 |
|
0x06 顺序与位置
先公有, 后私有; 先重写, 后实现; 先一般, 后个性.
以 Activity
类文件为例, 按以下顺序进行文件组织:
1 | package 当前包名 |
其它的类文件参照该原则进行组织.
当一个类有多个构造方法时, 或是多个同名方法时, 这些方法应该按参数从少到多的顺序出现在一起, 切忌分开来写.
0x07 更多
最好不要让这个文档有
更多
了.
实现无尽的需求已经够让我们喝一壶的了. 谁还希望在这时有更多的束缚?