[关闭]
@Vee 2017-10-26T02:35:10.000000Z 字数 8610 阅读 614

Android 开发规约

Android


一、代码规约

(一) 命名规约

1.1 类命名

  1. 类名使用 UpperCamelCase 风格,尽量避免缩写,除非该缩写是众所周知的, 比如HTML, URL,如果类名称中包含单词缩写,则单词缩写的每个字母均应大写。

    正例:MarcoPolo / UserDO / XmlService / TcpUdpDeal / TaPromotion
    反例:macroPolo / UserDo / XMLService / TCPUDPDeal / TAPromotion

  2. 抽象类命名使用 Abstract 或 Base 开头;异常类命名使用 Exception 结尾。测试类的命名以它要测试的类的名称开始,以Test结束。例如:HashTestHashIntegrationTest

  3. 接口(interface):命名规则与类一样采用大驼峰命名法,多以able或ible结尾,如
    interface Runnableinterface Accessible

描述 例如
Activity 类 Activity为后缀标识 欢迎页面类WelcomeActivity
Adapter类 Adapter 为后缀标识 新闻详情适配器 NewDetailAdapter
解析类 Parser为后缀标识 首页解析类HomePosterParser
工具方法类 Utils或Manager为后缀标识(与系统或第三方的Utils区分)或功能+Utils 线程池管理类:ThreadPoolManager日志工具类:LogUtils(Logger也可)打印工具类:PrinterUtils
数据库类 以DBHelper后缀标识 新闻数据库:NewDBHelper
Service类 以Service为后缀标识 时间服务TimeService
BroadcastReceiver类 以Receiver为后缀标识 推送接收JPushReceiver
ContentProvider类 以Provider为后缀标识 ShareProvider
自定义的共享基础类 以Base开头 BaseActivity,BaseFragment

1.2 方法命名

方法名都以lowerCamelCase风格编写。

方法名通常是动词或动词短语。

方法 说明
initXX() 初始化相关方法,使用init为前缀标识,如初始化布局initView()
isXX() checkXX() 方法返回值为boolean型的请使用is或check为前缀标识
getXX() 返回某个值的方法,使用get为前缀标识
setXX() 设置某个属性值
handleXX()/processXX() 对数据进行处理的方法
displayXX()/showXX() 弹出提示框和提示信息,使用display/show为前缀标识
updateXX() 更新数据
saveXX() 保存数据
resetXX() 重置数据
clearXX() 清除数据
removeXX() 移除数据或者视图等,如removeView();
drawXX() 绘制数据或效果相关的,使用draw前缀标识

1.3 变量命名

非常量字段名以lowerCamelCase风格的基础上改造为如下风格:基本结构为scopeVariableNameType

scopetype说明如下:

scope:范围

非公有,非静态字段命名以m开头。

静态字段命名以s开头。

公有非静态字段命名以p开头。

公有静态字段(全局变量)命名以g开头。

例子:

  1. public class MyClass {
  2. int mPackagePrivate;
  3. private int mPrivate;
  4. protected int mProtected;
  5. private static MyClass sSingleton;
  6. public int pField;
  7. public static int gField;
  8. }

使用1字符前缀来表示作用范围,1个字符的前缀必须小写,前缀后面是由表意性强的一个单词或多个单词组成的名字,而且每个单词的首写字母大写,其它字母小写,这样保证了对变量名能够进行正确的断句。

Type:类型

考虑到Android中使用很多UI控件,为避免控件和普通成员变量混淆以及更好达意,所有用来表示控件的成员变量统一加上控件缩写作为后缀(文末附有缩写表)。

对于普通变量一般不添加类型后缀,UI控件统一添加类型后缀,请参考文末的缩写表。

注意:
1. 如果项目中使用ButterKnife,则不添加m前缀,以lowerCamelCase风格命名。
2. 中括号是数组类型的一部分,数组定义如下:String[] args;
反例:使用 String args[]的方式来定义

1.4 常量命名

常量命名全部大写,单词间用下划线隔开,力求语义表达完整清楚,不要嫌名字长。

正例:MAX_STOCK_COUNT
反例:MAX_COUNT

1.5 参数名

参数名以lowerCamelCase风格编写。
参数应该避免用单个字符命名。

1.6 局部变量名

局部变量名以lowerCamelCase风格编写,比起其它类型的名称,局部变量名可以有更为宽松的缩写。
虽然缩写更宽松,但还是要避免用单字符进行命名,除了临时变量和循环变量。
即使局部变量是final和不可改变的,也不应该把它示为常量,自然也不能用常量的规则去命名它。

1.7 临时变量

临时变量通常被取名为ijkmn,它们一般用于整型;cde,它们一般用于字符型。 如:for (int i = 0; i < len ; i++)

1.8 其他规约

  1. 代码中的命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束。

    反例:_name / __name / $Object / name_ / nameZ$ / Object$

  2. 代码中的命名严禁使用拼音与英文混合的方式,更不允许直接使用中文的方式。

    说明:正确的英文拼写和语法可以让阅读者易于理解,避免歧义。注意,即使纯拼音命名方式 也要避免采用。
    正例:alibaba / taobao / youku / hangzhou 等国际通用的名称,可视同英文。
    反例:DaZhePromotion [打折] / getPingfenByName() [评分] / int 某变量 = 3

  3. POJO 类中布尔类型的变量,都不要加 is,否则部分框架解析会引起序列化错误。 反例:定义为基本数据类型 Boolean isDeleted;的属性,它的方法也是 isDeleted(),RPC框架在反向解析的时候,“以为”对应的属性名称是 deleted,导致属性获取不到,进而抛出异 常。

  4. 包名统一使用小写,点分隔符之间有且仅有一个自然语义的英语单词。包名统一使用 单数形式,但是类名如果有复数含义,类名可以使用复数形式。

    正例: 应用工具类包名为 com.alibaba.open.util、类名为 MessageUtils(此规则参考 spring 的框架结构)

  5. 杜绝完全不规范的缩写,避免望文不知义。

    反例:AbstractClass“缩写”命名成 AbsClasscondition“缩写”命名成 condi,此类随 意缩写严重降低了代码的可阅读性。

  6. 接口类中的方法和属性不要加任何修饰符号(public 也不要加),保持代码的简洁 性,并加上有效的 Javadoc 注释。尽量不要在接口里定义变量,如果一定要定义变量,肯定是 与接口方法相关,并且是整个应用的基础常量。

    正例:接口方法签名:void f(); 接口基础常量表示:String COMPANY = "alibaba";
    反例:接口方法定义:public abstract void f();
    说明:JDK8 中接口允许有默认实现,那么这个 default 方法,是对所有实现类都有价值的默认实现。

  7. 枚举类名建议带上 Enum 后缀,枚举成员名称需要全大写,单词间用下划线隔开。

    说明:枚举其实就是特殊的常量类,且构造方法被默认强制是私有。
    正例:枚举名字为 ProcessStatusEnum 的成员名称:SUCCESS / UNKNOWN_REASON

(二)、常量定义

  1. 不允许任何魔法值(即未经定义的常量)直接出现在代码中。

    反例:String key = "Id#taobao_" + tradeId; cache.put(key, value);

  2. long 或者 Long 初始赋值时,使用大写的 L,不能是小写的 l,小写容易跟数字 1 混 淆,造成误解。

    说明:Long a = 2l; 写的是数字的 21,还是 Long 型的 2?

  3. 不要使用一个常量类维护所有常量,按常量功能进行归类,分开维护。

    说明:大而全的常量类,非得使用查找功能才能定位到修改的常量,不利于理解和维护。
    正例:缓存相关常量放在类 CacheConsts 下;系统配置相关常量放在类 ConfigConsts 下。

  4. 常量的复用层次有五层:跨应用共享常量、应用内共享常量、子工程内共享常量、包内共享常量、类内共享常量。

    1. 跨应用共享常量:放置在二方库中,通常是 client.jar 中的 constant 目录下。
    2. 应用内共享常量:放置在一方库中,通常是 modules 中的 constant 目录下。

      反例:易懂变量也要统一定义成应用内共享常量,两位攻城师在两个类中分别定义了表示 “是”的变量:
      类 A 中:public static final String YES = "yes";
      类 B 中:public static final String YES = "y";
      A.YES.equals(B.YES),预期是 true,但实际返回为 false,导致线上问题。

    3. 子工程内部共享常量:即在当前子工程的 constant 目录下。
    4. 包内共享常量:即在当前包下单独的 constant 目录下。
    5. 类内共享常量:直接在类内部 private static final 定义。

(三)、代码格式

  1. 大括号的使用约定。如果是大括号内为空,则简洁地写成{}即可,不需要换行;如果 是非空代码块则:

    1) 左大括号前不换行。
    2) 左大括号后换行。
    3) 右大括号前换行。
    4) 右大括号后还有 else 等代码则不换行;表示终止的右大括号后必须换行。

  2. 左小括号和字符之间不出现空格;同样,右小括号和字符之间也不出现空格。详见 第 5 条下方正例提示。

    反例:if (空格 a == b 空格)

  3. if/for/while/switch/do 等保留字与括号之间都必须加空格。

  4. 任何二目、三目运算符的左右两边都需要加一个空格。

    说明:运算符包括赋值运算符=、逻辑运算符&&、加减乘除符号等。

  5. 采用 4 个空格缩进,禁止使用 tab 字符。

    说明:如果使用 tab 缩进,必须设置 1 个 tab 为 4 个空格。IDEA 设置 tab 为 4 个空格时, 请勿勾选 Use tab character;而在 eclipse 中,必须勾选 insert spaces for tabs。

    正例: (涉及 1-5 点)

    1. public static void main(String[] args) {
    2. // 缩进 4 个空格
    3. String say = "hello";
    4. // 运算符的左右必须有一个空格
    5. int flag = 0;
    6. // 关键词 if 与括号之间必须有一个空格,括号内的 f 与左括号,0 与右括号不需要空格
    7. if (flag == 0) {
    8. System.out.println(say);
    9. }
    10. // 左大括号前加空格且不换行;左大括号后换行
    11. if (flag == 1) {
    12. System.out.println("world");
    13. // 右大括号前换行,右大括号后有 else,不用换行
    14. } else {
    15. System.out.println("ok");
    16. // 在右大括号后直接结束,则必须换行
    17. }
    18. }
  6. 注释的双斜线与注释内容之间有且仅有一个空格。

    正例:// 注释内容,注意在//注释内容之间有一个空格。

  7. 单行字符数限制不超过 120 个,超出需要换行,换行时遵循如下原则:

    1) 第二行相对第一行缩进 4 个空格,从第三行开始,不再继续缩进,参考示例。
    2) 运算符与下文一起换行。
    3) 方法调用的点符号与下文一起换行。
    4) 方法调用时,多个参数,需要换行时,在逗号后进行。
    5) 在括号前不要换行,见反例。

    正例:

    1. StringBuffer sb = new StringBuffer();
    2. // 超过 120 个字符的情况下,换行缩进 4 个空格,点号和方法名称一起换行
    3. sb.append("zi").append("xin")...
    4. .append("huang")...
    5. .append("huang")...
    6. .append("huang");

    反例:

    1. StringBuffer sb = new StringBuffer();
    2. // 超过 120 个字符的情况下,不要在括号前换行
    3. sb.append("zi").append("xin")...append
    4. ("huang");
    5. // 参数很多的方法调用可能超过 120 个字符,不要在逗号前换行
    6. method(args1, args2, args3, ...
    7. , argsX);
  8. 方法参数在定义和传入时,多个参数逗号后边必须加空格。

    正例:下例中实参的"a",后边必须要有一个空格。 method("a", "b", "c");

  9. IDE 的 text file encoding 设置为 UTF-8; IDE 中文件的换行符使用 Unix 格式, 不要使用 Windows 格式。

  10. 没有必要增加若干空格来使某一行的字符与上一行对应位置的字符对齐。
    正例:

    1. int a = 3;
    2. long b = 4L;
    3. float c = 5F;
    4. StringBuffer sb = new StringBuffer();

    说明:增加 sb 这个变量,如果需要对齐,则给 a、b、c 都要增加几个空格,在变量比较多的 情况下,是一种累赘的事情。

  11. 方法体内的执行语句组、变量的定义语句组、不同的业务逻辑之间或者不同的语义 之间插入一个空行。相同业务逻辑和语义之间不需要插入空行。

    说明:没有必要插入多个空行进行隔开。

二、资源命名规约

(一)、Layout资源

1. contentView命名

必须以全部单词小写,单词间以下划线分割,使用名词或名词词组。

所有Activity或Fragment的contentView必须与其类名对应,对应规则为:将所有字母都转为小写,将类型和功能调换(也就是后缀变前缀)。

例如:activity_main.xml

2. Dialog命名

规则:dialog_描述.xml
例如:dialog_hint.xml

3. PopupWindow命名

规则:ppw_描述.xml
例如:ppw_info.xml

4. 列表项命名

规则:item_描述.xml
例如:item_city.xml

5. 包含项命名

规则:模块_(位置)描述.xml
例如:activity_main_head.xmlactivity_main_bottom.xml
注意:通用的包含项命名采用:项目名称缩写_描述.xml
例如:xxxx_title.xml

(二)、Drawable资源

全部小写,采用下划线命名法,加前缀区分

命名模式:可加后缀 _small 表示小图, _big 表示大图,逻辑名称可由多个单词加下划线组成,采用以下规则:

说明:用途也指控件类型(具体见附录UI控件缩写表

例如:

名称 说明
btn_main_home.png 按键用途_模块名_逻辑名称
divider_maket_white.png 分割线用途_模块名_颜色
ic_edit.png 图标用途_逻辑名称
bg_main.png 背景用途_逻辑名称
btn_red.png 红色按键用途_颜色
btn_red_big.png 红色大按键用途_颜色
ic_head_small.png 小头像用途_逻辑名称
bg_input.png 输入框背景用途_逻辑名称
divider_white.png 白色分割线用途_颜色
bg_main_head 主模块头部背景图片用途_模块名_逻辑名称
def_search_cell 默认搜索界面单元图片用途_模块名_逻辑名称
ic_more_help 更多帮助图标用途_逻辑名称
divider_list_line 列表分割线用途_逻辑名称
sel_search_ok 搜索界面确认选择器用途_模块名_逻辑名称
shape_music_ring 音乐界面环形形状用途_模块名_逻辑名称

如果有多种形态,如按钮选择器:sel_btn_xx.xml

名称 说明
sel_btn_xx 按钮图片使用btn_整体效果(selector)
btn_xx_normal 按钮图片使用btn_正常情况效果
btn_xx_pressed 按钮图片使用btn_点击时候效果
btn_xx_focused state_focused聚焦效果
btn_xx_disabled state_enabled (false)不可用效果
btn_xx_checked state_checked选中效果
btn_xx_selected state_selected选中效果
btn_xx_hovered state_hovered悬停效果
btn_xx_checkable state_checkable可选效果
btn_xx_activated state_activated激活的
btn_xx_windowfocused state_window_focused

注意:使用AndroidStudio的插件SelectorChapek可以快速生成selector,前提是命名要规范。

(三)、Values资源

资源文件的命名规则使用前缀_模块名_逻辑名称的方式,单词全部小写,例如:

1. String资源

stringsname命名使用下划线命名法,采用以下规则:模块名+逻辑名称,这样方便同一个界面的所有string都放到一起,方便查找。

名称 说明
main_menu_about 主菜单按键文字
friend_title 好友模块标题栏
friend_dialog_del 好友删除提示
login_check_email 登录验证
dialog_title 弹出框标题
button_ok 确认键
loading 加载文字

有关 Color 和 Dimen 资源的命名,尚待商量确定。

(四)、Anim资源

全部小写,采用下划线命名法,加前缀区分。

具体动画采用以下规则:模块名_逻辑名称

例如:refresh_progress.xmlmarket_cart_add.xmlmarket_cart_remove.xml

普通的tween动画采用如下表格中的命名方式:动画类型_方向

名称 说明
fade_in 淡入
fade_out 淡出
push_down_in 从下方推入
push_down_out 从下方推出
push_left 推向左方
slide_in_from_top 从头部滑动进入
zoom_enter 变形进入
slide_in 滑动进入
shrink_to_middle 中间缩小

三、注释规约

  1. 类、类属性、类方法的注释必须使用 Javadoc 规范,使用/**内容*/格式,不得使用 // xxx 方式。

    说明:在 IDE 编辑窗口中,Javadoc 方式会提示相关注释,生成 Javadoc 可以正确输出相应注 释;在 IDE 中,工程调用方法时,不进入方法即可悬浮提示方法、参数、返回值的意义,提高 阅读效率

  2. 所有的抽象方法(包括接口中的方法)必须要用 Javadoc 注释、除了返回值、参数、 异常说明外,还必须指出该方法做什么事情,实现什么功能。

    说明:对子类的实现要求,或者调用注意事项,请一并说明

  3. 所有的类都必须添加创建者和创建日期。

  4. 方法内部单行注释,在被注释语句上方另起一行,使用//注释。方法内部多行注释 使用/* */注释,注意与代码对齐。

  5. 所有的枚举类型字段必须要有注释,说明每个数据项的用途。

  6. 与其“半吊子”英文来注释,不如用中文注释把问题说清楚。专有名词与关键字保持 英文原文即可。

    反例:“TCP 连接超时”解释成“传输控制协议连接超时”,理解反而费脑筋。

  7. 代码修改的同时,注释也要进行相应的修改,尤其是参数、返回值、异常、核心逻辑 等的修改。

    说明:代码与注释更新不同步,就像路网与导航软件更新不同步一样,如果导航软件严重滞后, 就失去了导航的意义。

  8. 谨慎注释掉代码。在上方详细说明,而不是简单地注释掉。如果无用,则删除。

    说明:代码被注释掉有两种可能性:1)后续会恢复此段代码逻辑。2)永久不用。前者如果没 有备注信息,难以知晓注释动机。后者建议直接删掉(代码仓库保存了历史代码)

  9. 对于注释的要求:第一、能够准确反应设计思想和代码逻辑;第二、能够描述业务含 义,使别的程序员能够迅速了解到代码背后的信息。完全没有注释的大段代码对于阅读者形同
    天书,注释是给自己看的,即使隔很长时间,也能清晰理解当时的思路;注释也是给继任者看 的,使其能够快速接替自己的工作。

  10. 好的命名、代码结构是自解释的,注释力求精简准确、表达到位。避免出现注释的 一个极端:过多过滥的注释,代码的逻辑一旦修改,修改注释是相当大的负担。

    反例:

    1. // put elephant into fridge
    2. put(elephant, fridge);

    方法名 put,加上两个有意义的变量名 elephant 和 fridge,已经说明了这是在干什么,语 义清晰的代码不需要额外的注释。

  11. 对于尚待修改的地方打上TODO标签并及时清理TODO标签内容。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注