Android 开发规范

前言

在 Android 开发中,一个良好的开发习惯,以及一个开发规范可能会让你少走很多弯路,也会一定程度上的提高代码的可读性,可维护性和可拓展性。当随着需求的不断变更,代码量的不断增加,需要重构的时候,你会明白一个好的开发规范是多么的重要。

1 命名规范

1. 1 包名

  • 采用反域名命名规则,全部使用小写字母;
  • 一级包名为 com,二级包名为xxx(可以是公司域名或者个人命名),三级包名根据应用进行命名,四级包名为模块名或层级名。
包名 说明
com.xx.应用名称缩写.activity 页面用到的Activity类 (activitie层级名用户界面层)
com.xx.应用名称缩写.base 基础共享的类
com.xx.应用名称缩写.adapter 页面用到的Adapter类 (适配器的类)
com.xx.应用名称缩写.util 此包中包含:公共工具方法类(util模块名)
com.xx.应用名称缩写.bean 下面可分:vo、po、dto 此包中包含:JavaBean类
com.xx.应用名称缩写.model 此包中包含:模型类
com.xx.应用名称缩写.db 数据库操作类
com.xx.应用名称缩写.view (或者 com.xx.应用名称缩写.widget ) 自定义的View类等
com.xx.应用名称缩写.service Service服务
com.xx.应用名称缩写.receiver BroadcastReceiver服务
com.xx.应用名称缩写.pref 首选项
  • 只需导入用到的类,不得用*导入包下所有类;
  • 导入类时,系统类在上方,自定义类在下方。

注意
如果项目采用 MVP,所有 MVP 抽取出来的接口都放置在相应模块的 i 包 下,所有的实现都放置在相应模块的 impl 下


1.2 类名

采用大驼峰命名法,尽量避免缩写,除非该缩写是众所周知的,比如 HTML、URL,如果类名称包含单词缩写,则单词缩写的每个字母均应大写。

描述 例如
Activity 类 Activity 为后缀标识 欢迎页面类 WelcomeActivity
Adapter 类 Adapter 为后缀标识 新闻详情适配器 NewDetailAdapter
解析类 Parser 为后缀标识 首页解析类 HomePosterParser
工具方法类 UtilManager 为后缀标识(与系统或第三方的 Utils 区分)或功能+Util 1. 线程池管理类:ThreadPoolManager;2. 日志工具类:LogUtil(Logger也可);3. 打印工具类:PrinterUtil
数据库类 DBHelper 后缀标识 新闻数据库:NewDBHelper
Service 类 Service 为后缀标识 时间服务 TimeService
Receiver 类 Receiver 为后缀标识 推送接收 PushReceiver
ContentProvider Provider 为后缀标识
自定义的共享基础类 Base 开头 BaseActivity,BaseFragment
  • 测试类的命名以它要测试的类的名称开始,以 Test 结束。例如:HashTest 或 HashIntegrationTest
  • 接口(interface):命名规则与类一样采用大驼峰命名法,多以 ableible 结尾,如 interface Runable,interface Accessible

注意
如果项目采用 MVP,所有 Model、View、Presenter 的接口都以 I 为前缀,不加后缀,其他的接口采用上述命名规则。


1.3 方法名

  • 动词或动名词;
  • 采用小驼峰命名法。
方法 说明
initXX() 初始化相关方法,使用 init 为前缀标识,如初始化布局 initView()
toXX() 按钮点击事件,如:toLogin()
isXX() ,checkXX() 方法返回值为 boolean 型的请使用 is 或 check 为前缀标识
setXX() 设置方法,使用 get 为前缀标识,如:setData()
getXX() 返回某个值的方法,使用 get 为前缀标识
handleXX() 对数据进行处理的方法,尽量使用 handle 为前缀标识
displayXX(),showXX() 弹出提示框和提示信息,使用 display,show 为前缀标识
saveXX() 与保存数据相关的,使用 save 为前缀标识
resetXX() 对数据重组的,使用 reset 前缀标识
clearXX() 清除数据相关的
removeXXX() 清除数据相关的
drawXXX() 绘制数据或效果相关的,使用 draw 前缀标识

下划线可能出现在 JUnit 测试方法名称中用以分隔名称的逻辑组件。一个典型的模式是:test_,例如testPop_emptyStack。并不存在唯一正确的方式来命名测试方法。


1.4 常量名

  • 全部字母大写,用下划线分隔单词。
 public staticfinal String ACTION_MAIN="android.intent.action.MAIN";

每个常量都是一个静态final字段,但不是所有静态final字段都是常量。在决定一个字段是否是一个常量时,考虑它是否真的感觉像是一个常量


1.5 变量名

  • 非静态字段命名以 m 开头,表示 member,如:mRun;
  • 静态字段命名以 s 开头,表示 static,如:sInstance;
  • 公有非静态字段命名以 p 开头;
  • 公有静态字段(全局变量)命名以 g 开头;
  • 控件变量添加组件前缀,顺序在所有者前缀之后,例如:全局名称 mBtnNext,局部名称 btnNext。
private int mPrivate;  
protected int mProtected; 
int mPackagePrivate; 
private static MyClass sSingleton;  
public int pField;  
public static int gField; 
  • 除单例模式外一般不得使用静态变量;
  • 构造方法采用递增方式(参数多的写在后面);
  • 仅在项目内使用的实体类不使用JavaBean进行封装,直接将成员变量访问修饰符修改为非 private;
  • 实体类中固定值的成员变量可设置成 final,并通过构造函数初始化;
  • 实体类中不得随意修改的成员变量可添加下划线前缀以作区别,例如:
class User{public int _id;}
  • 一般不使用 System.out 输出,而是使用 Log 中的方法;
  • 使用 BuildConfig.DEBUG 标记对 Log 进行封装,只在调试时输出重要信息,正式版不输出;
  • 一般 try……catch 只捕获需要的异常;
  • catch 块不得为空,至少应当将异常信息输出;

说明
集合添加如下后缀:List、Map、Set
数组添加如下后缀:Arr


2 资源文件命名

2.1 Layout 命名

  • 全部小写,采用下划线命名法
类型 说明 举例
Activity 命名 activity_描述.xml activity_main.xml
Fragment 命名 fragment_描述.xml fragment_hint.xml
Dialog 命名 dialog_描述.xml dialog_hint.xml
PopupWindow 命名 ppw_描述.xml ppw_info.xml
ListView 的 item 命名 item_list_描述.xml item_list_city.xml
GridView 的 item 命名 item_grid_描述.xml item_grid_city.xml
ListView 的 HeaderView 命名 header_list_描述.xml header_list_city.xml
ListView 的 FooterView 命名 item_list_描述.xml footer_list_city.xml
包含项命名 模块_(位置)描述.xml activity_main_head.xml、activity_main_bottom.xml

2.2 Drawable 命名

  • 全部小写,采用下划线命名法,加前缀区分
类型 举例
按钮 btn_main_home.png
分割线 div_maket_white.png
图标 ic_edit.png
背景 bg_main.png
默认 def_user_head_portrait.png

如果有多种形态,如按钮等除

名称 功能
btn_xx 按钮图片使用 btn_整体效果
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
bg_head 背景图片使用 bg_功能_说明
def_search_cell 默认图片使用 def_功能_说明
ic_more_help 图标图片使用 ic_功能_说明
seg_list_line 具有分隔特征的图片使用 seg_功能_说明
sel_ok 选择图标使用sel_功能_说明

2.3 Colors 的命名

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

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

2.4 Strings 命名

类型{范围}功能,范围可选。
以下为几种常用的命名:

  • 页面标题,命名格式为:title_页面
  • 按钮文字,命名格式为:btn_按钮事件
  • 标签文字,命名格式为:label_标签文字
  • 选项卡文字,命名格式为:tab_选项卡文字
  • 消息框文字,命名格式为:toast_消息
  • 编辑框的提示文字,命名格式为:hint_提示信息
  • 图片的描述文字,命名格式为:desc_图片文字
  • 对话框的文字,命名格式为:dialog_文字
  • menu的item文字,命名格式为:action_文字

2.5 动画命名

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

普通的 tween 动画采用如下表格中的命名方式

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

2.6 Layout 中 id 的命名

命名模式为:view缩写_view的逻辑名称

<!-- 这是标题栏的标题 -->
<TextView
    android:id="@+id/tv_header_title"
     ... />

<!-- 这是登录按钮 -->
<Button 
    android:id="@+id/btn_login"
    ... />

** 附录 **

  • 表1 UI 控件缩写表:
控件 缩写 举例
LinearLayout ll llFriend或者mFriendLL
RelativeLayout rl rlMessage或mMessageRL
FrameLayout fl flCart或mCartFL
TableLayout tl tlTab或mTabTL
Button btn btnHome或mHomeBtn
ImageButton ibtn btnPlay或mPlayIBtn
TextView tv tvName或mNameTV
EditText et etName或mNameET
ListView lv lvCart或mCartLV
ImageView iv ivHead或mHeadIV
GridView gv gvPhoto或mPhotoGV
RadioButton rbtn -
ToggleButton tbtn -
CheckBox chk -
View v -
ScrollView sclv -
ProgressBar pbar -
  • 表2 常见的英文单词缩写:
名称 缩写
icon ic(主要用在 app 的图标)
color cl(主要用于颜色值)
divider di(主要用于分隔线,不仅包括 Listview 中的 divider,还包括普通布局中的线)
selector sl(主要用于某一 view 多种状态,不仅包括 Listview 中的 selector,还包括按钮的 selector)
average avg
background bg(主要用于布局和子布局的背景)
buffer buf
control ctrl
delete del
document doc
error err
escape esc
increment inc
infomation info
initial init
image img
Internationalization I18N
length len
library lib
message msg
password pwd
position pos
server srv
string str
temp tmp
window wnd(win)

3 编码规范

  • 源文件编码格式为 UTF-8;
  • java代码中不出现中文,最多注释中可以出现中文;
  • 服务端可以实现的,就不要放在客户端;
  • 引用第三方库要慎重,避免应用大容量的第三方库,导致客户端包非常大;
  • 处理应用全局异常和错误,将错误以邮件的形式发送给服务端;
  • 图片的.9处理;
  • 使用静态变量方式实现界面间共享要慎重;
  • 单元测试(逻辑测试、界面测试);
  • 不要重用父类的 handler,对应一个类的 handler 也不应该让其子类用到,否则会导致 message.what 冲突;
  • strings.xml 中使用 %1$s 实现字符串的通配;
  • 数据一定要效验,例如字符型转数字型,如果转换失败一定要有缺省值;服务端响应数据是否有效判断;
  • 对于未完成的方法,使用 TODO 加以标记;
void write(byte[] buf, File file) {
      // TODO: Write buf to file
}
  • 若功能已完成,但存在效率等潜在问题时,使用 XXX 加以标记;
void parseXML(File file) {
      // XXX: Maybe SAX is better
      DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
      Document doc = builder.parse(file);
}
  • 若代码存在严重问题或仅用于调试,使用 FIXME 加以标记;
boolean login(String name, String pwd) {
    // FIXME: Remove this line before publishing
    System.out.println("name=" + name + ", password=" + pwd);
    if (users.containsKey(name) && users.get(name).equals(pwd))
        return true;
        return false;
}
  • 如果 for、while 等代码块过长,可以在结尾处标记循环变量
for (int position = 0; position < 10; position++) {
    ……
} // end for: position
    while (mRun) {
    ……
} // end while: mRun
  • 如果 if 的条件大于2个,则必须写注释
if (isBluetooth // If Bluetooth network is on
                 || isWifi // If WLAN network is on
                 || is3g // if 3g network is on
       ) {}

4 代码提交规范

无论使用的是 GIT,还是 SVN 都需要遵守下面这些规范;

  • 工作目录要及时更新,不要和服务器有太大的差别;
  • 提交代码时,如果出现冲突,必须仔细分析解决,不可以强行提交;
  • 提交代码之前先在本地进行测试,确保项目能编译通过,且能够正常运行,不可盲目提交;
  • 必须保证服务器上的版本是正确的,项目有错误时,不要进行提交;
  • 提交之前先更新;
  • 提交时注意不要提交本地自动生成的文件,比如我们 Android Studio 项目中的 ideabuild文件夹是不需要提交的;
  • 不要提交自己不明白的代码;
  • 提前协调好项目组成员的工作计划,减少冲突;
  • 对提交的信息采用明晰的标注(写注释)。

5 架构规范

5.1 架构方式

是选择 MVP,MVC,MVVM ,Flux 还是 Clean 架构。 Dagger2 + RxJava + Retrofit/OkHtttp + Loader + Databinding + ContentProvider,还是谷歌官方架构示例android-architecture

5.2 开源库的选取以及封装

对开源库的选取,一般都需要选择比较稳定的版本,作者在维护的项目,要考虑作者对issue的解决,以及开发者的知名度等各方面。选取之后,一定的封装是必要的。

5.3 架构提示

抽象层面

  • 提高架构的拓展性是有必要的。以前的框架可能会出现功能不足的情况,但是因为这点是不可预见的,所以我们选择框架时一定要了解好框架本身的扩展性如何,或者对框架有较深的理解,能够自己扩展框架;
  • 提高架构的稳定性;
  • 必要的架构的文档;

具体操作

  • Activity 和 Fragment 里面有许多重复的操作以及操作步骤,所以我们都需要提供一个 BaseActivity 和 BaseFragment ,让所有的 Activity 和 Fragment 都继承这个基类。
  • 数据提供统一的入口。无论是在 MVP、MVC 还是 MVVM 中,提供一个统一的数据入口,都可以让代码变得更加易于维护。
    比如,我使用的 DataManager,里面的 http、preference、eventpost、database ,都在 DataManger 里面进行操作,我们只需要与 DataManger 打交道。
  • 多用组合, 少用继承。
  • 提取方法, 去除重复代码。对于必要的工具类抽取也很重要,这在以后的项目中是可以重用的。
  • 引入 Dagger2 减少模块之间的耦合性。Dagger2 是一个依赖注入框架,使用代码自动生成创建依赖关系需要的代码。减少很多模板化的代码,更易于测试,降低耦合,创建可复用可互换的模块。
    Google官方MVP+Dagger2架构详解
  • 项目引入 RxJava + RxAndroid 这些响应式编程,可以极大的减少逻辑代码;
  • 通过引入事件总线,如:Event Bus、OTTO、RxBus。它允许我们在 Data Layer 中发送事件,以便 View Layer 中的多个组件都能够订阅到这些事件,减少回调。
  • 添加日志打印,用于查找错误等,如:loggertimber
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容

  • 个人总结的 Android 开发规范,其中控件缩写及 Android 资源文件命名部分不是很确定,有待商榷。Jav...
    牙锅子阅读 1,565评论 0 6
  • 请看完结版:Android开发规范(完结版)
    Blankj阅读 8,599评论 25 115
  • title: Android开发规范 摘要 1 前言 2 命名规范 3 资源文件规范 4 版本统一规范 5 第三方...
    大白栈阅读 1,187评论 0 16
  • 2017年7月14日早上我们6:05就起床了,吃完早饭姨爸带着我和连星皓还有姐姐还有我妹相怡希去篮球场打篮...
    10小石头相昊辰阅读 567评论 1 5
  • 现代社会多有无神论者往往都持着旧物就该死去,当代人岂可念旧。虽不知存在的意义到底是什么? 当人们什么都可以放下...
    三木七阅读 267评论 0 1