android规范文档,请勿转载!谢谢...
1. 概述
1.1 前言
团队协作能够显著有效的提高工作效率,而代码规范在团队协作当中也起了很重要的作用;这份文档参考了Google Java 编程风格规范和Google官方Android编码风格规范。该文档仅供参考,适用于android团队。1.2 目的
形成统一的代码规范,减少编码过程中bug的数量,增加代码的观赏性、扩展性以及可维护性。
2. 开发准备
2.1 开发工具使用android studio。
2.2 代码管理使用管理工具git以及git flow思想进行管理。
3. 代码风格
- 3.1 文件格式和文件类型
utf-8格式和java文件。
- 3.2 程序块缩进
不以tab进行缩行处理,以space空格键进行缩行
- 3.3 程序块空行
a.空行将逻辑相关的代码块分隔开,以提高可读性。
b.一个源文件的两个片段之间。
c.类声明和接口声明之间。
d.两个方法之间。
e.方法内的布局变量与方法的第一条语句之间。
f.一个方法内的两个逻辑段之间。
- 3.4 长语句与长表达式
循环或判断当中若是有较长的表达式或语句,要进行适当的划分,一般
以操作符为分割对象,操作符位于分隔行之首。
- 3.5 长参数
方法当中有多个参数时,以方法内部逗号进行划分,逗号位于分隔行之首。
- 3.6 短语句
每行只能存在一条语句,每条语句结束后应当进行换行处理。
- 3.7 大括号{}的使用
a.大括号一般与if else 、for、do while语句一起使用,即便是一条空语句
也应该把大括号加上。
b.左大括号前不换行、左大括号后换行、右大括号前换行
c.如果右大括号后是一个语句、函数体或类的终止,则右大括号后换行,否则不换行。
public void method() {//Good
}
public void method(){//Bad
}
public void method()//Bad{
}
- 3.8 自动换行
一般情况下,一行长代码为了避免超出列限制(80或100个字符)而被分成多行,很多时候,对于同一串代码已经有了好几种有效的自动换行方式。
- 3.9 变量声明
不要使用组合声明。如:int i, j,k;
int i, j, k;//Bad
int i;//Good
int j;//Good
- 3.10 参数和返回值
a.一个方法的参数尽量不易过多,如若过多,做好换行处理
public void method(String params01 , String params02
, String params03…) {
}//good
b.一个方法返回值是错误码,用异常处理去替代它
c.尽可能不要使用null,替代为异常或者空变量,List则可以返回Collections.emptyList形式。
- 3.11 import语句
a.impory语句不使用通配符,不换行。
import java.lang.*;//Bad
import java.lang.string;//Good
b.顺序和间距
- Import语句可以分为以下几组,按照这个顺序,每组由一个空行分隔:
所有的静态导入独立成组
- com.google imports(仅当这个源文件是在com.google包下)
- 第三方的包。每个顶级包为一组,字典序。例如:android,com,jnuit,org,
sun
- Java imports5.javax imports组内不空行,按字典序排序
- 3.12 使用标准的Java Annotation
a.Annotation位于java语言其它 修饰符之前。简单的marker annotation(@Override等)可以和语言元素放在同一行。如果存在多个annotation,或者annotation是参数化的,则应该按字母顺序各占一行来列出。
内建三种Annotation | Annotation注解内容 |
---|---|
@DePrecated | 只要某个语言元素已经不再建议使用了,必须使用@DePrecated annotation。如果使用了@Deprecated annotation ,则必须同时进行@Deprecated javadoc标记,并且给出一个替代的实现方案。此外,@Deprecated 的方法仍然是能正常执行的。 |
@Override | 只要某个方法覆盖了已过时的或继承自超类的方法,就必须使用@Override annotation。 |
@SuppressWarnings | @SuppressWarnings annotation 仅用于无法消除编译警告的场合。如果警告确实经过测试”不可能消除”,则必须使用@SuppressWarnings annotation,已确保所有的代码警告都能真实反映代码中的问题。当需要使用@SuppressWarnings annotation时,必须在前面加上TODO注释行,用于解释“不可能解除警告”的条件 |
b.Todo注释一般应用于未完成的功能区域。
c.对那些临时性的、短期的、够棒但不完美的代码,使用TODO注释
TODO注释应该包含全部大写的TODO,后跟一个冒号:
//TODO: Remove this Code for version code
//TODO: Change this Code for reason
d.注释的语言当前以中文为主。
- 3.13 Java异常的处理
a.不要忽略异常,即使你的代码看起来永远不会出现这种情况或者处理这种异常并不重要,但忽略异常的这种行为会在代码中埋下一颗定时炸弹,so,在代码中以某种规矩处理所有的异常。
public void stringToInt(String value){
try{
int intValue = Integer.parseInt(value);
}catch(NumberFormatException){
}
}
空的catch语句在java中会让人感到忧虑,绝对不要这样做,替代方案有以下几
种。
向方法的调用者抛出异常
public void stringToInt(String value) throws NumberFormatException{
int intValue = Integer.parseInt(value);
}
根据抽象级别抛出新的异常。
public void stringToInt(String value) throws SelfDefineException{
try{
int intValue = Integer.parseInt(value);
}catch(NumberFormatException){
throw new SelfDefineException(“value”+invalid number);
}
}
默默的处理错误并在catch中替换为合适的值。
public void stringToInt(String value){
int intValue;
try{
intValue = Integer.parseInt(value);
}catch(NumberFormatException){
intValue = 0;
}
}
b.不要捕获顶级的Exception
绝大部分情况下,捕获顶级的Exception或Throwable都是不合适的,Throwable更
不合适,因为它还包含了Error异常。
try{
ioOperationMethod();//may be throw IOException
classCastOperationMethod();//may be throw CastException
objectInvokeMethod();//may be throw NullPointException
}catch(Exception e){
handlerError();//just handler with one operation
}
不可直接全部捕获为Exception异常,正常的处理方式为:
分开捕获每一种异常,在一条try语句后面跟随多个catch语句块。
再次抛出异常,很多时候我们不需要捕获这个异常,只要让这个方法抛出这个异
常即可。
- 3.14 其它
4.命名规范
4.1 包名全部小写,连续的单词只是简单的链接起来,不适用下划线;采用反域名命名规则,一级包名为公司性质,二级包名为公司名或个人,三级包名为应用,四级包名为模块名或层级名等。
4.2 类名采用大驼峰驼峰命名法,既采用功能名+类型名的命名方式,尽量避免缩写,除非该缩写是众所周知的;如果类名众包含缩写单词,则单词缩写的每个字母均为大写。对于继承自安卓组件的类来说,类名应该以该组件名结尾,例如 : SignInActivity , SignInFragment , ImageUploaderService , ChangePasswordDialog ;对于工具类来说,命名方式应该以其完成功能开始,以 Utils 结束 ,例如 : HttpUtils , ImageUtils .
类 | 包名 | 命名格式 | 示例 |
---|---|---|---|
Activity | *.ui.activity | 功能名+activity | MainActivity LoginActivity… |
Service | *.service | 功能名+Service | DownLoadService… |
BroadCastReceiver | *.service | 功能名+Receiver | JpushReceiver AlarmReceiver… |
Fragment | *.ui.fragment | 功能名+Fragment | MainFragment FoundFragment… |
Dialog | *.ui.widget | 功能名+Dialog | CustomDialog RoundProgressBar… |
Adapter | *.ui.adapter | 功能名+Adapter | GoodsAdapter CouponAdapter… |
基础功能类 | *.app | Base+父类名 | BaseActivity BasePresenter… |
工具类和管理类 | *.ui.utils | 功能名+Utils/Manager | DbUtilsFileUtils… |
4.3 接口/抽象类命名方式和类名差不多,一般在接口类前加上大写的I/A,表示这是一个Interface/Abstract类。例:IView,Ipresenter…
4.4 资源文件:以小写加下划线的方式命名
- 4.4.1 drawable文件的命名规范:
Asset Type | Prefix 前缀 | Example |
---|---|---|
Action bar | ab_ | ab_stacked.9.png |
Button | btn_ | btn_send_pressed.9.png |
Dialog | dialog_ | dialog_top.9.png |
Divider | divider_ | divider_horizontal.png |
Icon | ic_ | ic_star.png |
Menu | menu_ | menu_submenu_bg.9.png |
Notification | notification_ | notification_bg.9.png |
Tabs | tab_ | tab_pressed.9.png |
- 4.4.2 icons文件的命名规范:
Asset Type | Prefix 前缀 | Example |
---|---|---|
Icons | ic_ | ic_star.png |
Launcher icons | ic_launcher | ic_launcher.png |
Menu icons and Action Bar icons | ic_menu | ic_menu_archive.png |
Status bar icons | ic_stat_notify | ic_stat_notify_msg.png |
Tab icons | ic_tab | ic_tab_recent.png |
Dialog icons | ic_dialog | ic_dialog_info.png |
- 4.4.3 选择器状态文件的命名规范:
Asset Type | Prefix 前缀 | Example |
---|---|---|
Normal | _normal | btn_order_normal.png |
Pressed | _pressed | btn_order_pressed.png |
Focused | _focused | btn_order_focused.png |
Disabled | _disabled | btn_order_disabled.png |
Selected | _selected | btn_order_selected.png |
- 4.4.4 布局文件:
Component组件 | Class Name | Example |
---|---|---|
Activity | MainActivity | activity_main.xml |
Fragment | SiteFragment | Fragment_site.xml |
Dialog | LoadingDialog | dialog_loading.xml |
Adapter Item | item_site.xml | |
其他视图 | view_head.xml |
- 4.4.5 string.xml、dimens.xml、colors.xml、styles.xml命名方式 ,遵循完整性 规范性 有序性原则,分块注释,不同模块区分开:
- layout常量要在string.xml中进行定义,且每个常量根据功能模块自成一组,如:
取消关注
…
您没有未使用的优惠劵哟~
…
- layout当中控件的margin、padding以及TextView的文本大小值定义在
dimens.xml
文件当中,sp采取的命名方式为size_具体数值,dp采取的命名方式为dp_具体数
值,如:
10sp
…
10dp
…
layout当中的复用样式定义到styles.xml当中。
- 4.4.6 动画文件 :
动画效果 | 命名风格 | Example |
---|---|---|
淡入/淡出 | fade_in/fade_out | fade_in.xml |
从右淡入 | fade_right_in | fade_right_in.xml |
从右弹入 | push_right_in | push_right_in.xml |
从右滑入 | slide_in_from_right | slide_in_from_right.xml |
- 4.5 类方法采用 小驼峰 命名法,根据函数所完成功能命名 ,如 changView(),在函数头写对于函数功能、参数和返回值的注释,一个函数请尽量保持在50行 之内 如:
/**
* 获取两个数中最大的一个
* @param value1 参与比较的第一个数
* @param value2 参与比较的第二个数
* @return 两个参数中最大的一个数
*/
public int max(int value1, int value2) {
return (value1 > value2) ? value1 : value2;
}
- 4.6 控件id命名
控件 | 前缀缩写 |
---|---|
RelativeLayout | rl |
LinearLayout | ll |
FrameLayout | fl |
TextView | tv |
Button | btn |
ImageButton | ibtn |
ImageView | iv |
CheckBox | cb |
RadioButton | rb |
EditText | edt |
ToggleButton | tbtn |
ProgressBar | pb |
VideoView | vv |
WebView | wv |
ScrollView | sv |
ListView | lv |
GridView | gv |
RecycleView | rv |
- 4.7 变量名采用小驼峰命名
a.非公有,非静态成员变量命名前面加m(member,表示成员变量之意),如,控件的宽高mWidth,mHeight
b.静态类变量前面加s(static,表示静态变量之意),如,一个静态的单例sSingleInstance
c.公有非静态字段命名以p开头
d.公有静态字段(全局变量)命名以g开头
e.局部变量名
- 局部变量名以LowerCamelCase风格编写,比起其它类型的名称;局部变量可以
有更为宽松的缩写。
- 虽然缩写更宽松,但还是要避免用单字符进行命名,除了临时变量和循环变量。
即使局部变量final是不可改变的,也不应该把它表示为常量,自然不能用常量的规
则去命名它。
- 临时变量通常被取名为i,j,k,m和n,它们一般用于整型;c,d,e,它们一般
用于字符型。如:for(int i=0 ; i
5. 编码规范
- 5.1 Activity当中的onCreate方法分为三个部分
a.initVariable()初始化变量以及获取Intent传值。
b.initViews()控件的初始化操作。
c.presenter.getXXData()当前界面的数据获取操作。
- 5.2 布局的适配方案,xml当中的每个控件都得在activity当中初始化完毕后,重新调
取测量方法例:
- measure(mViewFoot,0,142)
- measure(mIvTabOne,78,78)
- measure(mIvTabTwo,78,78)
…
measure内部实现原理
ViewGroup.LayoutParams params = view.getLayoutParams();
params.width = resetWidth;
params.height = resetHeight;
view.setLayoutParams(params);
5.3 使用retrofit+gson的形式定义module层的数据载体。
5.4 activity之间的传值坚持用Intent携带序列化实体数据的方式。禁止为了省事使用全局变量进行传值的方式。
5.5 为节省内存,使用ArrayList<>作为数据的承载体,而不是HashMap;HashMap<>由android自封装的SparseArray<>进行取代。
5.6 Glide图片处理框架,由 *.util.glid包下的GlideUtil类实现glide图片处理方法的封装
5.7 控件的点击事件由代码控制,简单逻辑可以在xml文件中通过onclick标签实现.
5.8 SharePreferences只用于简单的配置消息,对于对象,还是需要保存在本地文件中。
5.9 项目当中的单一圆角背景图片,使用自定义shape进行处理。
5.10 数据库采用项目中自定义的脚本进行表的创建删除以及数据的增删改查操作。
- 脚本升级文件的命名方式 (dbName_oldVer_newVer),如:test.db_1_2表
示将test数据库版本从1升到2。
- 数据库中表的命名规范,全部大写,单词用下划线_链接。
增加表的升级脚本
@orm.create(test1)
@orm.create(test2);
@orm.create(test3);
- 删除表的升级脚本
drop table if exists TEST1_FIELD;
drop table if exists TEST2_FIELD;
drop table if exists TEST3_FIELD;
- 如果表中有增加、减少、修改列(对象对应的字段增加、减少、修改)
drop table if exists test1;
@orm.create(test4);
//先删除原先的表再创建
drop table if exists test2;
@orm.create(test5);
- 5.6 上线打包注意的细节
a.更改
当中的请求接口,由测试环境更改为正式环境。
b.关闭app本身应用的log日志开关以及第三方sdk应用的log日志开关。
检查应用的版本号,做版本号的递增处理。
c.build.gradle文件当中 对minifyEnable做混淆的操作,在proguard-rules.pro做对应保留类的操作。
d.对比git coding上的master分支和feature分支代码,检查数据库表是否有变化,如果有,通过脚本做对应的升级、修改数据库版本号以及测试数据库相关更改是否通过。