android编码规范

参考文章:http://keeganlee.me/post/android/20150709 http://www.jianshu.com/p/0a984f999592
https://source.android.com/source/code-style

源文件结构规范

一个源文件包含(按顺序地):

  • 许可证或版权信息(如有需要)
  • package语句
  • import语句
  • 一个顶级类(只有一个)以上每个部分之间用一个空行隔开。

许可证或版权信息

如果一个文件包含许可证或版权信息,那么它应当被放在文件最前面。

package语句

package 语句不换行,列限制并不适用于package语句。(即package语句写在一行里)

import语句

import不要使用通配符

即,不要出现类似这样的import语句:import java.util.*;

不要换行

import语句不换行,列限制并不适用于import语句。(每个import语句独立成行)

顺序和间距

import语句可分为以下几组,按照这个顺序,每组由一个空行分隔:

  • 导入 Android 包
  • 导入第三方包(com、junit、net、org)
  • java 和 javax

类声明

只有一个顶级

类声明每个顶级类都在一个与它同名的源文件中(当然,还包含.java后缀)。

类成员顺序

类的成员顺序对易学性有很大的影响,但这也不存在唯一的通用法则。不同的类对成员的排序可能是不同的。
最重要的一点,每个类应该以某种逻辑去排序它的成员,维护者应该要能解释这种排序逻辑。比如, 新的方法不能总是习惯性地添加到类的结尾,因为这样就是按时间顺序而非某种逻辑来排序的。

区块划分

建议使用注释将源文件分为明显的区块,区块划分如下

  1. 常量声明区
  2. UI控件成员变量声明区
  3. 普通成员变量声明区
  4. 内部接口声明区
  5. 初始化相关方法区
  6. 事件响应方法区
  7. 普通逻辑方法区
  8. 重载的逻辑方法区
  9. 发起异步任务方法区
  10. 异步任务回调方法区
  11. 生命周期回调方法区(出去onCreate()方法)
  12. 内部类声明区

重载:永不分离

当一个类有多个构造函数,或是多个同名方法,这些函数/方法应该按顺序出现在一起,中间不要放进其它函数/方法。

注释规范

文件头注释

文件头注释使用以下格式,需要将版权声明进行替换

/**   
 * Copyright (C) 2017 zhangyang. All rights reserved.
 *
 * @Package: ${PACKAGE_NAME} 
 * @Description: 
 * @author ${USER}  
 * @date ${TIME} 
 */

在android studio中的配置方法为:

android编码规范_第1张图片
C3A89FBE-C80C-4BAC-BE50-ABB1CA3EAA5C.png

类和接口注释

类和接口的注释使用以下的注释格式:

/**
 * @description $description$
 
 * @author $user$
 * @time $date$ $time$
 */

在android studio中的配置方式如下,首先选择Editor->Live Templates,然后选择右侧的加号,选择Template Group,命名为custom,再点击加号,选择Live Template,命名为cmc(cmc是快捷键,可以自己任意命名),然后可以对该自定义模板进行描述,并选择应用的场景为java->Declaration,详见下面的第二幅图。最后注意需要点击Edit variables,对相应的值配置由程序动态赋值,例如$user$,配置为user(),即使用当前计算机用户名,减少工作量。

android编码规范_第2张图片
800F5CE2-A4ED-47B2-A457-C1BDD7B7A7BC.png
android编码规范_第3张图片
197466AF-65FB-4ACE-98B0-E9659E04CB45.png
android编码规范_第4张图片
D4CB4A9A-B12C-49B1-997B-C46D56ECB354.png

方法注释

方法注释采用如下格式:

    /**
     * @description  用户注册

     * @author zhangyang
     * @time 2017/6/19 上午9:38
     * @param userName 用户名
     * @param password 密码
     * @return
     */
    public int registerUser(String userName, String password);

在android studio中的配置方式与上面的类和接口的配置方式相同:

/**
 * @description $description$
 
 * @author $user$
 * @time $date$ $time$
 * @param $param$  
 * @return $return$ 
 */

这里我命名快捷键为cmf。注意:在android studio里面没有找到自定义模板自动生成参数的方案,如果使用默认的方法生成注释方案,则除了参数不能增加其他的自定义字段。因此需要编写代码时,在相应方法上输入cmf生成注释后,还需要手动编辑@param,有几个参数需要编辑几个。

android编码规范_第5张图片
image.png

变量和常量注释

下面几种情况下的常量和变量,都要添加注释说明,在上方添加注释。//和内容后面有一个空格。

  • 接口中定义的所有常量
  • 公有类的公有常量
  • 枚举类定义的所有枚举常量
  • 实体类的所有属性变量
// 普通用户
public static final int TYPE_COMMON_USER = 1; 

// 管理员用户
public static final int TYPE_ADMIN_USER = 2; 

书写规范

编码方式

编码方式统一用UTF-8. Android Studio默认已是UTF-8,只要不去改动它就可以了。

缩进

缩进统一为4个空格

花括号书写

  • 左大括号前不换行
  • 左大括号后换行
  • 右大括号前换行
  • 如果右大括号是一个语句、函数体或类的终止,则右大括号后换行; 否则不换行

例如,如果右大括号后面是else或逗号,则不换行。

return new MyClass() {    
    @Override public void method() {        
        if (condition()) {
            try {
                something();
            } catch (ProblemException e) {
                recover();
            }
        }
    }
};

空格的使用

if、else、for、switch、while等逻辑关键字与后面的语句留一个空格隔开。

if (booleanVariable) { 
    // TODO while booleanVariable is true
} else { 
    // TODO else
}

运算符两边各用一个空格隔开。

int result = a + b; //Good, = 和 + 两边各用一个空格隔开
int result=a+b; //Bad,=和+两边没用空格隔开

方法的每个参数之间用一个空格隔开。

public void method(String param1, String param2); // Good,param1后面的逗号与String之间隔了一个空格
method(param1, param2); // Good,方法调用时,param1后面的逗号与param2之间隔了一个空格
method(param1,param2); // Bad,没有用一个空格隔开

空行的使用

将逻辑相关的代码段用空行隔开,以提高可读性。空行也只空一行,不要空多行。在以下情况需用一个空行:

  • 两个方法之间
  • 方法内的两个逻辑段之间
  • 方法内的局部变量和方法的第一条逻辑语句之间
  • 常量和变量之间

表达式过长书写

当一个表达式无法容纳在一行内时,可换行显示,另起的新行用8个空格缩进。

someMethod(longExpression1, longExpression2, longExpression3, 
        longExpression4, longExpression5);

变量声明

一行声明一个变量,不要一行声明多个变量,这样有利于写注释。

// 参数1
private String param1; 

// 参数2
private String param2; 

行宽设置

行宽设置为100,设置格式化时自动断行到行宽位置。

android编码规范_第6张图片
image.png

方法规模

一个方法最多不要超过40行代码(官方建议)。

常量定义

常量统一采用接口来定义,按模块和类型等划分。

文字和元素大小单位定义

官方建议文字大小的单位统一用sp,元素大小的单位统一用dp。从实际开发中看,文字大小采用sp,会导致文字大小随着系统设置字体的大小变化,导致布局出问题。因此我们项目组初期采用的都是使用dp,但目前使用的是以1280*720基准尺寸,横坐标分成1280份,纵坐标分成720份,其他按比例进行伸缩,实际是以px为单位处理。

字符串定义

应用中的字符串统一在strings.xml中定义,然后在代码和布局文件中引用。

颜色定义

颜色值统一在colors.xml中定义,然后在代码和布局文件中引用。另外,不要在代码和布局文件中引用系统的颜色,除了透明。

命名规范

包命名

域名反写+项目名称+模块名称,全部单词用小写字母。
例如
com.android.example.login

类和接口命名

使用大驼峰规则,用名词或名词词组命名,每个单词的首字母大写。
以下为几种常用类的命名:

  • activity类,命名以Activity为后缀,如:LoginActivity
  • fragment类,命名以Fragment为后缀,如:ShareDialogFragment
  • service类,命名以Service为后缀,如:DownloadService
  • adapter类,命名以Adapter为后缀,如:CouponListAdapter
  • 工具类,命名以Util为后缀,如:EncryptUtil
  • 模型类,命名以Model为后缀,如:LoginModel
  • 接口实现类,命名以Impl为后缀,如:ApiImpl

方法命名

使用小驼峰规则,用动词命名,第一个单词的首字母小写,其他单词的首字母大写。
以下为几种常用方法的命名:

  • 初始化方法,命名以init开头,例:initView
  • 按钮点击方法,命名以onClick开头,例:onclickLogin
  • 设置方法,命名以set开头,例:setData
  • 具有返回值的获取方法,命名以get开头,例:getData
  • 通过异步加载数据的方法,命名以load开头,例:loadData
  • 布尔型的判断方法,命名以is或has,或具有逻辑意义的单词如equals,例:isEmpty

控件缩写

控件 缩写 控件 缩写
TextView TV EditText ET
Button Btn ImageButton IBt
ImageView IV ListView LV
ProgressBar PB SeekBar SB
CheckBox CB LinearLayout LL
Relativelayout RL FrameLayout FL
ScrollView SV GridView GV

常量命名

全部为大写单词,单词之间用下划线分开。
public final static int PAGE_SIZE = 20;

变量命名

{范围描述+}意义描述+类型描述的组合,用驼峰式,首字母小写

  • 非公开且非静态字段的名称以 m 开头。
  • 静态字段的名称以 s 开头。
  • 其他字段以小写字母开头。
  • 公开静态 final 字段(常量)为全部大写并用下划线连接 (ALL_CAPS_WITH_UNDERSCORES)。
    例如:
public class MyClass {
    public static final int SOME_CONSTANT = 42;
    public int publicField;
    private static MyClass sSingleton;
    int mPackagePrivate;
    private int mPrivate;
    protected int mProtected;
}

控件id命名

控件缩写{范围}意义,范围可选,只在有明确定义的范围内才需要加上。





layout命名

组件类型{范围}功能,范围可选,只在有明确定义的范围内才需要加上。
以下为几种常用的组件类型命名:

  • activity_{范围_}功能,为Activity的命名格式
  • fragment_{范围_}功能,为Fragment的命名格式
  • dialog_{范围_}功能,为Dialog的命名格式
  • item_list_{范围_}功能,为ListView的item命名格式
  • item_grid_{范围_}功能,为GridView的item命名格式
  • header_list_{范围_}功能,为ListView的HeaderView命名格式
  • footer_list_{范围_}功能,为ListView的FooterView命名格式

strings的命名

模块类型{范围_}功能,范围可选。
以下为几种常用的命名(以登录模块为例):

  • 页面标题,命名格式为:login_title_页面
  • 按钮文字,命名格式为:login_btn_按钮事件
  • 标签文字,命名格式为:login_label_标签文字
  • 选项卡文字,命名格式为:login_tab_选项卡文字
  • 消息框文字,命名格式为:login_toast_消息
  • 编辑框的提示文字,命名格式为:login_hint_提示信息
  • 图片的描述文字,命名格式为:login_desc_图片文字
  • 对话框的文字,命名格式为:login_dialog_文字
  • menu的item文字,命名格式为:login_action_文字

colors的命名

前缀{控件}{范围}{_后缀},控件、范围、后缀可选,但控件和范围至少要有一个。例如bg_btn_send_normal

  • 背景颜色,添加bg前缀
  • 文本颜色,添加text前缀
  • 分割线颜色,添加div前缀
  • 公共的颜色,添加common前缀
  • 区分状态时,默认状态的颜色,添加normal后缀
  • 区分状态时,按下时的颜色,添加pressed后缀
  • 区分状态时,选中时的颜色,添加selected后缀
  • 区分状态时,不可用时的颜色,添加disable后缀

drawable的命名

前缀{控件}{范围}{_后缀},控件、范围、后缀可选,但控件和范围至少要有一个。

  • 图标类,添加ic前缀
  • 背景类,添加bg前缀
  • 分隔类,添加div前缀
  • 默认类,添加def前缀
  • 区分状态时,默认状态,添加normal后缀
  • 区分状态时,按下时的状态,添加pressed后缀
  • 区分状态时,选中时的状态,添加selected后缀
  • 区分状态时,不可用时的状态,添加disable后缀
  • 多种状态的,添加selector后缀(一般为ListView的selector或按钮的selector)

动画文件命名

动画类型_动画方向。

  • fade_in,淡入
  • fade_out,淡出
  • push_down_in,从下方推入
  • push_down_out,从下方推出
  • slide_in_from_top,从头部滑动进入
  • zoom_enter,变形进入
  • shrink_to_middle,中间缩小

编程实践

@Override:能用则用

只要是合法的,就把@Override注解给用上。

捕获的异常:不能忽视

除了下面的例子,对捕获的异常不做响应是极少正确的。(典型的响应方式是打印日志,或者如果它被认为是不可能的,则把它当作一个 AssertionError 重新抛出。)
如果它确实是不需要在catch块中做任何响应,需要做注释加以说明(如下面的例子)。

try {
  int i = Integer.parseInt(response);
  return handleNumericResponse();
} catch (NumberFormatException ok) {
  // it's not numeric; that's fine, just continue
}

return handleTextResponse(response);

例外:在测试中,如果一个捕获的异常被命名为expected,则它可以被不加注释地忽略。下面是一种非常常见的情形,用以确保所测试的方法会抛出一个期望中的异常,因此在这里就没有必要加注释。

try {
 emptyStack.pop();
 fail();
} catch (NoSuchElementException expected) {
}

使用 TODO 备注

为代码使用 TODO 备注是短期的临时解决方案,或者说足够好但并不完美。TODO 备注应该以全部大写的字符串 TODO 开头,后跟一个冒号:

// TODO: Remove this code after the UrlTable2 has been checked in.

// TODO: Change this to use a flag instead of a constant.

如果TODO 采用“在未来的某个日期做某事”的形式,请确保在其中包含一个非常具体的日期(“在 2005 年 11 月前修复”)或者一个非常具体的事件(“在所有生产环境合成器都可处理 V7 协议后移除此代码”)。

静态成员:使用类进行调用

使用类名调用静态的类成员,而不是具体某个对象或表达式。

Foo aFoo = ...;
Foo.aStaticMethod(); // good
aFoo.aStaticMethod(); // bad
somethingThatYieldsAFoo().aStaticMethod(); // very bad

Finalizers: 禁用

极少会去重载Object.finalize。

Tip:
不要使用finalize。如果你非要使用它,请先仔细阅读和理解Effective Java第7条款:"Avoid Finalizers",然后不要使用它。

谨慎使用日志记录

项目中请不要直接使用Log打印日志,应该至少对系统日志封装一个日志类,该类可以控制当前打印输出的日志级别或者打开和关闭日志打印。每个类定义一个常量TAG用来打印相应的类的日志,当功能开发稳定之后,请去掉开发打印的调试日志。

保持一致

总而言之:保持一致。如果正在修改代码,花几分钟时间看一下周围的代码并确定其样式。如果该代码在 if 语句周围使用空格,那么您也应该这样做。如果代码备注的周围是用星号组成的小方框,您也应该将备注放在这样的小方框内。

你可能感兴趣的:(android编码规范)