个人总结的 Android 开发规范,其中控件缩写及 Android 资源文件命名部分不是很确定,有待商榷。Java 部分编程风格请参考:Google Java 命名规范。
2017-02-13 更新:2017年开春之际,诚意献上重磅大礼:阿里巴巴Java开发手册,首次公开阿里官方Java代码规范标准。这套Java统一规范标准将有助于提高行业编码规范化水平,帮助行业人员提高开发质量和效率、大大降低代码维护成本。点此下载
约定
-
统一调整 IDE 的编码方式为 UTF-8
-
统一调整 IDE 的 Tab 缩进为 4 个空格
-
花括号不要单独一行,和它前面的代码同一行。而且,花括号与前面的代码之间用一个空格隔开。
public void method() { // Good } public void method() { // Bad } public void method(){ // Bad }
-
空格的使用:if、else、for、switch、while等逻辑关键字与后面的语句留一个空格隔开。
// Good if (booleanVariable) { // TODO while booleanVariable is true } else { // TODO else } // Bad 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之间隔了一个空格 public void method(param1, param2); // Good,方法调用时,param1后面的逗号与param2之间隔了一个空格 public void method(param1,param2); // Bad,没有用一个空格隔开
-
空行的使用,拒绝拖沓无分割,关联代码段放一块并与后面代码分割
- 两个方法之间
- 方法内的两个逻辑段之间
- 方法内的局部变量和方法的第一条逻辑语句之间
- 常量和变量之间
- 方法名和方法内第一条语句不要有空格
Activity.onCreate(),Fragment.onActivityCreated(),作为程序入口,不要写入太多代码,尽量保持只调用 initXXX() 方法,简单明了展示调用过程。如:initData(),initView()。可在 BaseActivity 、 BaseFragment 中实现 init 执行顺序,子类实现,即 模板方法模式。
Application 中只执行应用初始化相关操作,尽量不要涉及业务逻辑。如有,请单独剥离。参考第 6 条
单个方法体不要过长,最好不要超过一屏,竖屏显示器请无视~
一行声明一个变量,不要一行声明多个变量,这样有利于写注释。
代码任何地方不要拼错单词
-
代码必须格式化
Windows:CTRL + ALT + L Mac:OPTION + COMMAND + L
文字大小的单位统一用 sp,元素大小的单位统一用 dp;应用中的字符串统一在
/values/strings.xml
中定义;颜色值统一在/values/colors.xml
中定义;菜单定义统一放在/menu/****.xml
中;自定义View 属性统一在/values/attrs.xml
中;自定义drawable 文件统一在/drawable/****.xml
中;自定义样式统一在/values/styles.xml
。调用方法保持“临近原则”,被调用的方法,放在调用方法下方
-
用好 TODO 标记
- 记录想法,记录功能点,开发过程中可以利用 TODO 记录一下临时想法或为了不打扰思路留下待完善的说明
- 删除无用 TODO ,开发工具自动生成的 TODO ,或则已经完善的 TODO ,一定要删除。
-
处理“魔法数字”等看不懂的神秘数字
- 代码中不要出现数字,特别是一些标识不同类型的数字。
- 所有意义数字全部抽取到 Constant 公共类中,避免散布在各位类中。
- 所有有意义的字符串公共常量全部抽取到 Constant 公共类中
命名规范
命名除了要遵守以下规范,还得见名知意。
类和接口命名
使用大驼峰规则,用名词或名词词组命名,每个单词的首字母大写。
以下为几种常用类的命名:
- Activity 类,命名以 Activity 为后缀,如:
LoginActivity
- Fragment 类,命名以 Fragment 为后缀,如:
LoginFragment
- Service 类,命名以 Service 为后缀,如:
DownloadService
- Adapter 类,命名以 Adapter 为后缀,如:
CouponAdapter
- 工具类,命名以 Util 为后缀,如:
EncryptUtil
- 模型类,命名以 Info 为后缀,如:
UserInfo
- 接口实现类,命名以 Impl 为后缀,如:
ApiImpl
方法命名
使用小驼峰规则,用动词命名,第一个单词的首字母小写,其他单词的首字母大写。以下为几种常用方法的命名:
- 初始化方法,命名以 init 开头,例:initView()
- 按钮点击方法或 Activity 跳转方法,命名以 to 开头,例:toLogin()、toMainActivity()
- 设置方法,命名以 set 开头,例:setData()
- 具有返回值的获取方法,命名以 get 开头,例:getData()
- 通过异步加载数据的方法,命名以 load 开头,例:loadData()
- 布尔型的判断方法,命名以 is 或 has ,或具有逻辑意义的单词如 equals ,例:isEmpty()
常量命名
全部为大写单词,单词之间用下划线分开。常量一般放在 Constant
类
- Intent 参数以 PARAM_EXTRA 开头
// Intent 参数
public final static String PARAM_EXTRA_ID = "id";
public final static int PAGE_SIZE = 20;
变量命名
使用驼峰规则,首字母必须小写,使用名词或名词词组。要求简单易懂,富于描述,不允许出现无意义或错误单词。
- 普通成员变量命名以
mCamelCase
样式命名,静态变量以sCamelCase
命名 -
boolean 类型的成员变量命名可以不遵循第一条,以
lowerCamelCase
样式命名 - 控件变量命名都已 控件缩写 + 控件作用 来命名,如:登录按钮命名为 mBtnLogin;
- 参数变量、临时变量都已
lowerCamelCase
样式命名
public class MainActivity extends Activity {
private Button mBtnLogin;
private boolean isLaunch;
private boolean isEmpty(String text) {
// Todo...
}
}
补充:如果你使用 Android Studio 为开发工具,则可以通过如下方式设置变量前缀
![屏幕快照 2017-03-14 下午1.57.59](http://odsdowehg.bkt.clouddn.com/屏幕快照 2017-03-14 下午1.57.59.png)
控件缩写
常见控件缩写约定如下:
- TextView: tv
- EditText: edt
- Button: btn
- RadioButton: rb
- ImageButton: ib
- ImageView: iv
- RelativeLayout/LinearLayout/FrameLayout: rl , ll , fl
- ListView: lv
- WebView: web
- CheckBox: cbx
控件 id 命名
控件缩写_含义
<!-- 这是标题栏的标题 -->
<TextView
android:id="@+id/tv_header_title"
... />
<-- 这是登录按钮 -->
<Button
android:id="@+id/btn_login"
... />
布局文件命名
Activity 布局:activity_类名.xml,建议使用 Android Studio 生成(Command + N)
![屏幕快照 2017-03-14 下午1.59.31 w300](http://odsdowehg.bkt.clouddn.com/屏幕快照 2017-03-14 下午1.59.31.png)Fragment 布局:fragment_类名.xml
控件布局:widget_控件名.xml 或 layout_控件名.xml
Adapter Item 布局:item_适配器名.xml
strings.xml 命名
类型{范围}功能,范围可选。
以下为几种常用的命名:
- 页面标题,命名格式为:title_页面
- 按钮文字,命名格式为:btn_按钮事件
- 标签文字,命名格式为:label_标签文字
- 选项卡文字,命名格式为:tab_选项卡文字
- 消息框文字,命名格式为:toast_消息
- 编辑框的提示文字,命名格式为:hint_提示信息
- 图片的描述文字,命名格式为:desc_图片文字
- 对话框的文字,命名格式为:dialog_文字
- menu 的 item 文字,命名格式为:menu_文字
colors.xml 命名
前缀{控件}{范围}{_后缀},控件、范围、后缀可选,但控件和范围至少要有一个。
- 背景颜色,添加 bg 前缀
- 文本颜色,添加 text 前缀
- 分割线颜色,添加 div 前缀
- 区分状态时,默认状态的颜色,添加 normal 后缀
- 区分状态时,按下时的颜色,添加 pressed 后缀
- 区分状态时,选中时的颜色,添加 selected 后缀
- 区分状态时,不可用时的颜色,添加 disable 后缀
如:bg_loading_selected
drawable的命名
- 图标类,添加 ic 前缀
- 背景类,添加 bg 前缀
- 分隔类,添加 div 前缀
- 默认类,添加 def 前缀
- 区分状态时,默认状态,添加 normal 后缀
- 区分状态时,按下时的状态,添加 pressed 后缀
- 区分状态时,选中时的状态,添加 selected 后缀
- 区分状态时,不可用时的状态,添加 disable 后缀
- 多种状态的,添加 selector 后缀(一般为 ListView 的 selector 或按钮的 selector )
如:ic_launcher_pressed
注释规范
类和接口注释
类和接口统一添加javadoc注释,格式如下:
/**
* 类或接口的描述信息
*
* @author ${USER}
* @date ${DATE}
*/
public interface Login {
}
方法注释
下面几种方法,都必须添加注释,说明该方法的用途和参数说明,以及返回值。如不添加注释,方法和参数命名都要见名知意
- 接口中定义的所有方法
- 抽象类中自定义的抽象方法
- 抽象父类的自定义公用方法
- 工具类的公用方法
/**
* 登录
*
* @param loginName 登录名
* @param password 密码
* @param listener 回调监听器
*/
public void login(String loginName, String password, ActionCallbackListener listener);
变量和常量注释
下面几种情况下的常量和变量,都要添加注释说明,优先采用 右侧// 来注释,若注释说明太长则在上方添加注释。
- 接口中定义的所有常量
- 公有类的公有常量
- 枚举类定义的所有枚举常量
- 实体类的所有属性变量
public static final int TYPE_CASH = 1; // 现金券
public static final int TYPE_DEBIT = 2; // 抵扣券
public static final int TYPE_DISCOUNT = 3; // 折扣券
private int id; // 券id
private String name; // 券名称
private String introduce; // 券简介
发布及安全
版本管理
版本管理一般使用 Git
- 打包前必须pull一下代码
- 打包发版后,打上tag,push代码
- 打包后记得保存未加密过的包和mapping文件
建议使用 Git 进行版本管理,正式打包前先 pull 一下代码,保证发布版本为最新代码;版本发布后,打 tag 并 push 到服务器
-
正式版本需要打开 混淆,防止被反编译,gradle 项目在 buildTypes 中配置,混淆的配置文件为 proguard-android.txt
//必须在productFlavors之后 buildTypes { release { //开启混淆 minifyEnabled true //打包时移除不用资源 shrinkResources true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' //不同渠道使用不同的签名 signingConfig signingConfigs.sign } debug { signingConfig signingConfigs.sign } }
正式版本发布时需要关闭 Log ,防止 Log 调试信息的打印造成重要数据泄露。一般思路为封装 LogUtil,在其中根据 BuildConfig.Debug 判断是否输出日志
测试第三方SDK时,如对签名有要求,可以在 debug 时使用正式签名
正式发布版本时,可用第三方工具加密,如:360加密、爱加密,加密后最好测试下,可能会有兼容性问题
打包后记得保存未加密的包并保存 mapping 文件(列出了原始的类,方法和字段名与混淆后代码间的映射)
其它
-
控制语句
- 减少条件嵌套,不要超过3层
// Bad if(obj != null) { doSomething(); } // Good if(obj == null) { return; } doSomething();
- if语句必须用{}包括起来,即便是只有一句
- 方法
- 拆分臃肿方法,每个方法只作一件事
- 做同一个逻辑的方法,尽量靠近放到一块,方便查看
- 尽量不要使用 try catch 处理业务逻辑
- 使用JSON工具类,不要手动解析和拼装数据,如:Gson
- 重构相关书籍
- 《重构-改善既有代码的设计》
参考
关于 colors.xml 和 drawable 命名很久之前摘自某篇博文,忘记具体链接了,如有侵权,请联系我~