规范你的 Android 项目

通常我们为了项目的维护会定下一系列的规范开发来提高自己或者团队之间的写代码的效率,正所谓无规矩不成方圆。

Hello Android.jpg

Android Studio的使用

Android 开发首选 Android Studio,一个好的IDE能让你事半功倍。编码规范使用 Android Studio 默认的模板规范即可,这也是比较方便的方法。同时也要注意以下几点,可以让你的团队协作更加协调:

  1. 统一调整 IDE 的编码方式为 UTF-8
  2. 编辑完代码后不要忘记格式化(即 Ctrl+Alt+L 快捷键)
  3. 尽量保证团队之间的 IDE 版本与 Gradle 版本一致,最好的做法是及时更新保证与官方最新版一致。
  4. 代码提交前进行代码检查(Analyze->Inspect Code),可以消除代码中的警告,减少不必要的错误。
  5. 擅用 //TODO 注释来标记未做完或需要其他人接手的工作
  6. 善用AS插件来提高开发效率,像 GsonFormat——将json字符串转换成一个Java实体类的工具,CodeGlance——在右边可以预览代码,实现快速定位等工具都是非常棒的。

命名规范

最有效的命名方式是使用英文拼写和语法,可以让阅读者易于理解,尽量避免使用中文拼音的情况(常见地名和通用名称例外,比如HangZhou,alibaba等)。禁止使用中英文混合或者完全中文的方式。

包名

通常一个app需要一个顶级包名,而这个包名通常跟公司的域名相关。一级包名是顶级域名,通常为com,edu,gov,net,org等,二级包名为公司名,三级包名根据应用进行命名。

比如我的个人域名为 cpacm.net,那么我个人所做的app包名一般为net.cpacm.yourappname。

再来说如何分包?
分包的方式说法不一,有的人喜欢按照层次来分,比如说将所有 Activity 放在同一个包下。有的人喜欢按照功能来分,将一个功能的 ActivityModelAdapter等一些文件放入同一个包内。具体的例子可以参考谷歌的 iosched 样例。

我个人比较推荐的方式是按照功能进行分包,但同时会将数据层再单独分离出来,详细的例子可以看看我之前写的文章——说说我自己常用的 Android 架构。不过每个人的习惯并不一致,所以在这点上可以随意发挥,只要不导致整个项目结构混乱就成。

类名

一个类会包含(按顺序地):

  1. 许可证或版权信息(如有需要)
  2. package语句
  3. import语句
  4. 一个顶级类
    四个部分用一个空行隔开。

类名都以 UpperCamelCase 风格编写。

在 Android 中与系统相关的类通常以组件名为后缀标识。

  • Activity 类,命名为 Activity 为后缀,如 LoginActivity
  • Fragment 类,命名以 Fragment 为后缀,如 LoginFragment
  • Service 类,命名以 Service 为后缀,如 DownloadService
  • BroadcastReceiver类,命名以Receiver为后缀,如 JPushReceiver
  • ContentProvider类, 命名以Provider为后缀,如ShareProvider
  • Adapter 类,命名以 Adapter 为后缀,如 ListAdapter

其他一些常见的命名:

  • 工具管理类,命名以 Utils 或者 Manager 为后缀,如 EncryptUtilsUserManager
  • 实体类,命名以 Bean 或者 Info 为后缀,如 UserBean
  • 接口实现类,命名以 Impl 或者 Listener 为后缀,如 ApiImpl
  • 数据库类,命名以 Dao 或者 DbHelper 为后缀,如 UserDao
  • 自定义控件类,命名以 View 或者 Layout 为后缀,如 SimpleSliderLayout

方法名

方法名都以 lowerCamelCase 风格编写。

方法名通常是动词或动词短语。下划线可能出现在JUnit测试方法名称中用以分隔名称的逻辑组件。并不存在唯一正确的方式来命名测试方法。

常见的方法名称:

方法 说明
getXX()/setXX() 获取/设置属性值,如 getUserName()
isXX()/checkXX()/hasXX() 用于返回 Boolean 值的方法,如 isGirl(),hasPermission()
initXX() 初始化相关方法,如 initView()
loadXX()/handleXX() 读取数据或者对数据处理时的方法,如 loadData()
disPlayXX()/showXX() 显示相关信息,如 showToast()
... ...

一般方法的命名都是以动词为前缀,后面加上动作的对象。

常量名

常量名命名模式为 CONSTANT_CASE,全部字母大写,用下划线分隔单词。

// Constant
static final int NUMBER = 5;

// Not constant
static String nonFinal = "non-final";

这些名字通常是名词或名词短语。

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

变量名

在Google其它编程语言风格中使用的特殊前缀或后缀,如name_, mName, s_name和kName,在Java编程风格中都不再使用。

现在在 Android 非常量字段名的命名有两种方式,一种是在特定的字段名上加上特殊前缀或后缀,如普通成员变量命名以 mCamelCase 样式命名,静态变量以 sCamelCase 命名。另一种则是完全使用 lowerCamelCase 命名,如 camelCase 变量名。

虽然两种命名方式都可,但切记不要在同一个项目中同时使用,这样只会让代码看得糟糕。当然个人推荐变量名以 lowerCamelCase 风格编写。

参数名,局部变量名以 lowerCamelCase 风格编写

临时变量通常被取名为i、j、k、m和n,它们一般用于整型;c、d、e,它们一般用于字符型。

类型变量可用以下两种风格之一进行命名:

  1. 单个的大写字母,后面可以跟一个数字(如:E, T, X, T2)。
  2. 以类命名方式,后面加个大写的T(如:RequestT, FooBarT)。

关于Android中相关控件的命名,控件变量命名可以在后缀加上控件名称或者控件名称的缩写,如login+Button=loginButton/loginBtn。平常习惯控件名缩写的话推荐使用控件名称的缩写来作为后缀。

Android 资源文件

Android资源文件基本上都采取使用下划线_来连接词语。

布局文件 layout

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

界面相关布局

命名方式为 界面_模块.xml
通常 Activity 或者 Fragment 等类名要与其布局文件相对应,如:

LoginActivity.java -> activity_login.xml
BookFragment.java -> fragment_book.xml
DateDialog.java -> dialog_date.xml
SettingPopupWindow.java -> ppw_setting.xml

列表项布局

命名方式为 控件_模块_item.xml

一般关于列表项的命名则以 item 作为前缀,如:item_user.xml 表示这个布局文件用在用户列表中。

但我更喜欢下面这种方式的命名:
listview_user_item -> 表示这是用于 listview 的用户列表项。
recyclerview_user_item -> 表示这是用于 recyclerview 的用户列表项。
gridview_user_item -> 表示这是用于 gridview 的用户列表项。

而此时你自定义了一个 GroupView 需要列表项去填充,比如说一个 RefreshLayout:
refresh_user_item -> 表示这是用于 RefreshLayout 的用户列表项。

包含项

命名方式为 模块_描述.xml
在界面布局中,如 activity_user_header 表示为用户界面的头部布局。
在列表布局中,如 listview_user_header 表示为用户列表的头部布局。

图片资源 drawable

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

用途 命名规则 名称
图标 ic\_模块名[\_用途] ic_home 或 ic_media_info
普通文件 模块\_用途[\_状态描述] search_background 或者 layerlist_progress_horizontal 或者 btn_xx_focused

动画资源 anim

也是要全部小写,使用下划线来分隔词组。
命名规则为 模块_用途[_状态描述],如:

fade_out->淡出
push_down_in->从下方推入

菜单资源 menu

命名规则为: menu_模块[_用途]
如:menu_shelf -> 表示为书架上的菜单选项
其中菜单内部的id命名规则为 action_用途,如:action_manage

好吧,其实资源的命名没有那么多死板的规则,只要能看到自己命名的名字能立马明白它的作用就行了。当然不止自己也必须让团队的其他人能明白。

Values下的命名方式

色调(color)

禁止在layout直接使用 “#000000” 赋予颜色,
在你的colors.xml文件中应该只是映射颜色的名称一个ARGB值,而没有其它的。不要为特定的UI定义特定的颜色值,这样只会导致颜色值重复定义。

Don't

    <color name="chapter_select_area_bg">#fff5f5f5</color>
    <color name="content_text_color">#ff404040</color>
    <color name="et_hit_text_color">#ffacacac</color>

Do

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>

    <!-- 常用字体颜色 -->
    <color name="black">#000000</color>
    <color name="black_alpha">#8A000000</color>
    <color name="black_alpha_more">#64000000</color>
    <color name="black_normal">#DE000000</color>
    <color name="white">#FFFFFF</color>
    <color name="white_alpha">#8AFFFFFF</color>
    <color name="white_normal">#DEFFFFFF</color>
    <color name="white_normal_more">#33FFFFFF</color>
    <color name="white_less">#FFFAFA</color>
    
    
    <color name="transparent">#00000000</color>
</resources>

一个美观的 app 是不会充斥太多无用的色彩的。

尺寸(dimen)

尽量遵循 Material Design 的设计标准,比如字体的大小,页面左右空白16dp,列表上下间隔8dp等。

<resources>

    <dimen name="horizontal_margin">16dp</dimen>
    <dimen name="vertical_margin">16dp</dimen>
    <dimen name="horizontal_padding">16dp</dimen>
    <dimen name="vertical_padding">16dp</dimen>
    <dimen name="fab_margin">16dp</dimen>

    <!-- 页面统一间距 -->
    <dimen name="title_height">48dp</dimen>
    <dimen name="toolbar_height">48dp</dimen>
    <dimen name="tab_height">48dp</dimen>
    <dimen name="bar_height">56dp</dimen>
    <dimen name="edittext_height">56dp</dimen>
    <dimen name="caption_height">24dp</dimen>
    <dimen name="line_height">8dp</dimen>
    <dimen name="line_height_half">4dp</dimen>
    <dimen name="line_height_double">16dp</dimen>
    <dimen name="layout_height">72dp</dimen>

    <!-- 字体大小 -->
    <dimen name="text_display3">56sp</dimen>
    <dimen name="text_display2">45sp</dimen>
    <dimen name="text_display1">34sp</dimen>
    <dimen name="text_headline">24sp</dimen>
    <dimen name="text_title">20sp</dimen>
    <dimen name="text_subhead">16sp</dimen>
    <dimen name="text_body">14sp</dimen>
    <dimen name="text_caption">12sp</dimen>
    <dimen name="text_mini">10sp</dimen>
    <dimen name="text_menu">14sp</dimen>
    <dimen name="text_button">16sp</dimen>
    <dimen name="text_navi">18sp</dimen>

</resources>

尽量不要直接在布局文件里面写上具体的数值。

字符串(string)

strings的name命名使用下划线命名法,采用以下规则:模块名+逻辑名称
同样,禁止在代码中或者layout中直接填入字符,请在string.xml加入字符串。最好是按模块来分隔开字符串便于查找和修改,公用的写在最开始位置。

<resources>
    <string name="app_name">cpacm</string>

    <string name="open_string">open</string>
    <string name="close_string">close</string>

    <!--####################  Home模块  #####################-->

    <!-- bottom navi -->
    <string name="free">休闲</string>
    <string name="news">资讯</string>
    <string name="beauty">风采</string>
    <string name="study">学习</string>
    <string name="contract">互动</string>

    <!--#####################  Free模块  #####################-->
    <!-- tab -->
    <string name="music">音乐</string>
    <string name="movie">电影</string>
    <string name="book">图书</string>

</resources>

所有文字放在 strings.xml 中可以很方便的转换多国语言。

样式(style)

style的name命名使用大驼峰命名法。
当某部分xml属性代码重复过多时,请将其变成 style 以便重复利用。

<style name="ContentText">
    <item name="android:textSize">@dimen/font_normal</item>
    <item name="android:textColor">@color/basic_black</item>
</style>

自定义属性(attr)

attr的name命名使用大驼峰命名法。
在自定义控件或其他地方需要自定义属性名称时,除去直接加入attrs.xml中也可以新建一个 attr 文件,并在 attr 后加上功能名称。
attr_slider 表示一个轮播器控件的自定义属性。

layout内的id命名

命名模式为:模块名_view缩写,比如 search_btn

注释

类注释

每个类都必须要写上

  1. 创建时间
  2. 作者
  3. 类的作用描述
  4. 版本和联系方式(可选)
    这样团队就能知道这个类的作用是什么,原生产者是谁。
/**
 * <pre>
 *     author : cpacm
 *     e-mail : xxx@xx
 *     date   : 2017/03/21
 *     description   : xxxx描述
 *     version: 1.0
 * </pre>
 */
public class MainActivity {
      ...
}

在 Android Studio 中 Settings → Editor → File and Code Templates → Includes → File Header,输入模板。

方法注释

每个成员方法都应该有一个头注释,告诉我们这个方法做了什么,返回了什么。

/**
 * snackbar的显示
 */
public void showSnackBar(View view, @StringRes int toast) {
    Snackbar.make(view, getString(toast), Snackbar.LENGTH_SHORT).show();
}

设置Fix doc comment(Settings → Keymap → Fix doc comment)快捷键,AS便会生成模板。

块/行注释

主要作用是为一些代码进行补充说明,防止自己或团队的其他人无法理解代码的含义。

//指向书城界面
viewPager.setCurrentItem(2, false);

总结

上面的规范只是给个参考,适合自己或团队才是最好的。养成好的命名习惯才能写出优美的代码,这需要长时间的坚持才能培养出来。说实话,其实英语基础才是最重要的XD.
Java 更多的编写风格可以参考:Google Java 命名规范


参考资料:

  1. Google Java 命名规范
  2. 安卓开发规范
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,233评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,013评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,030评论 0 241
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,827评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,221评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,542评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,814评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,513评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,225评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,497评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,998评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,342评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,986评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,812评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,560评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,461评论 2 266

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,563评论 25 707
  • 文章来自https://github.com/Blankj/AndroidStandardDevelop#安卓开发...
    小庄bb阅读 702评论 0 1
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,099评论 18 139
  • 请看完结版:Android开发规范(完结版)
    Blankj阅读 8,547评论 25 115
  • 学会分享 文/侯国华 大多数人都看见小孩都喜欢逗他们玩,尤其是看见他们正在吃好吃的东西时,就问她给不给你吃,给了,...
    南风窗A阅读 322评论 1 0