Android开发规范

 做者博客地址:http://www.jianshu.com/p/419f5357357dcss

 

 

安卓开发规范(updating)

摘要

1 前言

为了利于项目维护以及规范开发,促进成员之间Code Review的效率,故提出如下开发规范,若有更好建议,欢迎到GitHub提issue,原文地址: 安卓开发规范(updating)html

2 AS规范

工欲善其事,必先利其器。java

  1. 尽可能使用最新版的IDE进行开发;
  2. 编码格式统一为UTF-8;
  3. 编辑完.java、 .xml等文件后必定要格式化(基本格式方面使用 AS 默认模板便可);
  4. 删除多余的import,减小警告出现,可利用AS的Optimize Imports(Settings → Keymap → Optimize Imports)快捷键;
  5. AS经常使用开发插件能够参考这里~AS经常使用开发插件

3 命名规范

代码中的命名严禁使用拼音与英文混合的方式,更不容许直接使用中文的方式。正确的英文拼写和语法可让阅读者易于理解,避免歧义。android

注意:即便纯拼音命名方式也要避免采用。但alibabataobaoyoukuhangzhou等国际通用的名称,可视同英文。ios

3.1 包名

包名所有小写,连续的单词只是简单地链接起来,不使用下划线,采用反域名命名规则,所有使用小写字母。一级包名是顶级域名,一般为com,edu,gov,net,org等,二级包名为公司名,三级包名根据应用进行命名,后面就是对包名的划分了,关于包名的划分,推荐使用按功能分,一开始咱们也是按照层去分包的,很坑爹。按照功能分可能你不是很好区分在哪一个功能中,不过也比你按照层区分要好找不少。具体能够参考这篇博文~Package by features, not layers,固然,咱们大谷歌也有相应的sample~iosched,其结构以下所示,很值得学习。git

java └─com └─google └─samples └─apps └─iosched │ AppApplication.java 定义Application类 │ Config.java 定义配置数据(常量) │ ├─about │ AboutActivity.java │ ├─appwidget │ ScheduleWidgetProvider.java │ ScheduleWidgetRemoteViewsService.java │ ├─debug │ │ DebugAction.java │ │ DebugActivity.java │ │ DebugFragment.java │ │ │ └─actions │ DisplayUserDataDebugAction.java │ ForceAppDataSyncNowAction.java │ ForceSyncNowAction.java │ ... │ ├─explore │ │ ExploreIOActivity.java │ │ ExploreIOFragment.java │ │ ExploreModel.java │ │ ... │ │ │ └─data │ ItemGroup.java │ LiveStreamData.java │ MessageData.java │ ... │ ├─feedback │ FeedbackApiHelper.java │ FeedbackConstants.java │ FeedbackHelper.java │ ... │ ├─framework │ FragmentListener.java │ LoaderIdlingResource.java │ Model.java │ ...定义interface并实现 │ ├─gcm │ │ GCMCommand.java │ │ GCMIntentService.java │ │ GCMRedirectedBroadcastReceiver.java │ │ ... │ │ │ └─command │ AnnouncementCommand.java │ NotificationCommand.java │ SyncCommand.java │ ... │ ├─io │ │ BlocksHandler.java │ │ HandlerException.java │ │ HashtagsHandler.java │ │ ...处理model │ │ │ ├─map │ │ └─model │ │ MapData.java │ │ Marker.java │ │ Tile.java │ │ │ └─model │ Block.java │ DataManifest.java │ Hashtag.java │ ... │ ├─map │ │ InlineInfoFragment.java │ │ MapActivity.java │ │ MapFragment.java │ │ ... │ │ │ └─util │ CachedTileProvider.java │ MarkerLoadingTask.java │ MarkerModel.java │ ... │ ├─model │ ScheduleHelper.java │ ScheduleItem.java │ ScheduleItemHelper.java │ ...定义model以及实现model相关操做 │ ├─myschedule │ MyScheduleActivity.java │ MyScheduleAdapter.java │ MyScheduleFragment.java │ ... │ ├─provider │ ScheduleContract.java │ ScheduleContractHelper.java │ ScheduleDatabase.java │ ...实现ContentProvider │ (也在此处定义provider依赖的其它类,好比db操做) │ ├─receiver │ SessionAlarmReceiver.java │ ├─service │ DataBootstrapService.java │ SessionAlarmService.java │ SessionCalendarService.java │ ├─session │ SessionDetailActivity.java │ SessionDetailConstants.java │ SessionDetailFragment.java │ ... │ ├─settings │ ConfMessageCardUtils.java │ SettingsActivity.java │ SettingsUtils.java │ ├─social │ SocialActivity.java │ SocialFragment.java │ SocialModel.java │ ├─sync │ │ ConferenceDataHandler.java │ │ RemoteConferenceDataFetcher.java │ │ SyncAdapter.java │ │ ... │ │ │ └─userdata │ │ AbstractUserDataSyncHelper.java │ │ OnSuccessListener.java │ │ UserAction.java │ │ ... │ │ │ ├─gms │ │ DriveHelper.java │ │ GMSUserDataSyncHelper.java │ │ │ └─util │ UserActionHelper.java │ UserDataHelper.java │ ├─ui │ │ BaseActivity.java │ │ CheckableLinearLayout.java │ │ SearchActivity.java │ │ ...BaseActivity以及自定义UI组件 │ │ │ └─widget │ AspectRatioView.java │ BakedBezierInterpolator.java │ BezelImageView.java │ ...自定义小UI控件 │ ├─util │ AboutUtils.java │ AccountUtils.java │ AnalyticsHelper.java │ ...工具类,提供静态方法 │ ├─videolibrary │ VideoLibraryActivity.java │ VideoLibraryFilteredActivity.java │ VideoLibraryFilteredFragment.java │ ... │ └─welcome AccountFragment.java AttendingFragment.java ConductFragment.java ...

参考Google I/O 2015的代码结构,按功能分包具体能够这样作:github

src └─com └─domain └─app │ AppApplication.java 定义Application类 │ Config.java 定义配置数据(常量) │ ├─framework │ 定义interface以及相关基类 │ ├─io │ 数据定义(model)、数据操做(好比json解析,但不包括db操做) │ ├─model │ 定义model(数据结构以及getter/setter、compareTo、equals等等,不含复杂操做) │ 以及modelHelper(提供便于操做model的api) │ ├─provider │ 实现ContentProvider,及其依赖的db操做 │ ├─receiver │ 实现Receiver │ ├─service │ 实现Service(好比IntentService),用于在独立线程中异步do stuff │ ├─ui │ 实现BaseActivity,以及自定义view和widget,相关的Adapter也放这里 │ ├─util │ 实现工具类,提供静态方法 │ ├─feature1 │ Item.java 定义model │ ItemHelper.java 实现modelHelper │ feature1Activity.java 定义UI │ feature1DAO.java 私有db操做 │ feature1Utils.java 私有工具函数 │ ...其它私有class │ ├─...其它feature

PBF(按功能分包Package By Feature)与PBL(按层分包Package By Layer)相比较有以下优点:数据库

  • package内高内聚,package间低耦合

哪块要添新功能,只改某一个package下的东西编程

按class职能分层(PBL)下降了代码耦合,但带来了package耦合,要添新功能,须要改model、dbHelper、view、service等等,须要改动好几个package下的代码,改动的地方越多,越容易产生新问题,不是吗?json

按功能分包(PBF),featureA相关的全部东西都在featureA包,feature内高内聚高度模块化,不一样feature之间低耦合,相关的东西都放在一块儿,还好找

  • package有私有做用域(package-private scope)

你负责开发这块功能,这个目录下全部东西都是你的

PBL的方式是把全部工具方法都放在util包下,小张开发新功能时候发现须要一个xxUtil,但它又不是通用的,那应该放在哪里?没办法,按照分层原则,咱们还得放在util包下,好像不太合适,但放在其它包更不合适,功能愈来愈多,util类也越定义越多。后来小李负责开发一块功能时发现须要一个xxUtil,一样不通用,去util包一看,怎么已经有了,并且还无法复用,只好放弃xx这个名字,改成xxxUtil……由于PBL的package没有私有做用域,每个包都是public(跨包方法调用是很日常的事情,每个包对其它包来讲都是可访问的)

若是是PBF,小张的xxUtil天然放在feautreA下,小李的xxUtil在featureB下,若是以为util好像是通用的,就去util包看看要不要把工具方法添进xxUtil,class命名冲突没有了

PBF的package有私有做用域,featureA不该该访问featureB下的任何东西(若是非访问不可,那就说明接口定义有问题)

  • 很容易删除功能

统计发现新功能没人用,这个版本那块功能得去掉

若是是PBL,得从功能入口到整个业务流程把受到牵连的全部能删的代码和class都揪出来删掉,一不当心就完蛋

若是是PBF,好说,先删掉对应包,再删掉功能入口(删掉包后入口确定报错了),完事

  • 高度抽象

解决问题的通常方法是从抽象到具体,PBF包名是对功能模块的抽象,包内的class是实现细节,符合从抽象到具体,而PBL弄反了

PBF从肯定AppName开始,根据功能模块划分package,再考虑每块的具体实现细节,而PBL从一开始就要考虑要不要dao层,要不要com层等等

  • 只经过class来分离逻辑代码

PBL既分离class又分离package,而PBF只经过class来分离逻辑代码

没有必要经过package分离,由于PBL中也可能出现尴尬的状况:

├─service │ MainServ.java

按照PBL,service包下的全部东西都是Controller,应该不须要Serv后缀,但实际上一般为了码起来方便,直接import service包,Serv后缀是为了不引入的class和当前包下的class命名冲突,固然,不用后缀也能够,得写清楚包路径,好比new net.ayqy.service.Main(),麻烦

而PBF就很方便,无需import,直接new MainServ()便可

  • package的大小有意义了

PBL中包的大小无限增加是合理的,由于功能越添越多

而PBF中包太大(包里class太多)表示这块须要重构(划分子包)

3.2 类名

类名都以UpperCamelCase风格编写。

类名一般是名词或名词短语,接口名称有时多是形容词或形容词短语。如今尚未特定的规则或行之有效的约定来命名注解类型。

名词,采用大驼峰命名法,尽可能避免缩写,除非该缩写是众所周知的, 好比HTMLURL,若是类名称中包含单词缩写,则单词缩写的每一个字母均应大写。

描述 例如
Activity 类 Activity为后缀标识 欢迎页面类WelcomeActivity
Adapter类 Adapter 为后缀标识 新闻详情适配器 NewDetailAdapter
解析类 Parser为后缀标识 首页解析类HomePosterParser
工具方法类 Utils或Manager为后缀标识(与系统或第三方的Utils区分)或功能+Utils 线程池管理类:ThreadPoolManager日志工具类:LogUtils(Logger也可)打印工具类:PrinterUtils
数据库类 以DBHelper后缀标识 新闻数据库:NewDBHelper
Service类 以Service为后缀标识 时间服务TimeService
BroadcastReceiver类 以Receiver为后缀标识 推送接收JPushReceiver
ContentProvider类 以Provider为后缀标识 ShareProvider
自定义的共享基础类 以Base开头 BaseActivity,BaseFragment

测试类的命名以它要测试的类的名称开始,以Test结束。例如:HashTestHashIntegrationTest

接口(interface):命名规则与类同样采用大驼峰命名法,多以able或ible结尾,如
interface Runnableinterface Accessible

注意:若是项目采用MVP,全部Model、View、Presenter的接口都以I为前缀,不加后缀,其余的接口采用上述命名规则。

3.3 方法名

方法名都以lowerCamelCase风格编写。

方法名一般是动词或动词短语。

方法 说明
initXX() 初始化相关方法,使用init为前缀标识,如初始化布局initView()
isXX() checkXX() 方法返回值为boolean型的请使用is或check为前缀标识
getXX() 返回某个值的方法,使用get为前缀标识
setXX() 设置某个属性值
handleXX()/processXX() 对数据进行处理的方法
displayXX()/showXX() 弹出提示框和提示信息,使用display/show为前缀标识
updateXX() 更新数据
saveXX() 保存数据
resetXX() 重置数据
clearXX() 清除数据
removeXX() 移除数据或者视图等,如removeView();
drawXX() 绘制数据或效果相关的,使用draw前缀标识

3.4 常量名

常量名命名模式为CONSTANT_CASE,所有字母大写,用下划线分隔单词。那,到底什么算是一个常量?

每一个常量都是一个静态final字段,但不是全部静态final字段都是常量。在决定一个字段是不是一个常量时,考虑它是否真的感受像是一个常量。例如,若是任何一个该实例的观测状态是可变的,则它几乎确定不会是一个常量。只是永远不打算改变对象通常是不够的,它要真的一直不变才能将它示为常量。

// Constants static final int NUMBER = 5; static final ImmutableListNAMES = ImmutableList.of("Ed", "Ann"); static final Joiner COMMA_JOINER = Joiner.on(','); // because Joiner is immutable static final SomeMutableType[] EMPTY_ARRAY = {}; enum SomeEnum { ENUM_CONSTANT } // Not constants static String nonFinal = "non-final"; final String nonStatic = "non-static"; static final SetmutableCollection = new HashSet(); static final ImmutableSetmutableElements = ImmutableSet.of(mutable); static final Logger logger = Logger.getLogger(MyClass.getName()); static final String[] nonEmptyArray = {"these", "can", "change"};

3.5 很是量字段名

很是量字段名以lowerCamelCase风格的基础上改造为以下风格:基本结构为scopeVariableNameType

scope:范围

非公有,非静态字段命名以m开头。

静态字段命名以s开头。

公有非静态字段命名以p开头。

公有静态字段(全局变量)命名以g开头。

例子:

public class MyClass { int mPackagePrivate; private int mPrivate; protected int mProtected; private static MyClass sSingleton; public int pField; public static int gField; }

使用1字符前缀来表示做用范围,1个字符的前缀必须小写,前缀后面是由表意性强的一个单词或多个单词组成的名字,并且每一个单词的首写字母大写,其它字母小写,这样保证了对变量名可以进行正确的断句。

Type:类型

考虑到Android中使用不少UI控件,为避免控件和普通成员变量混淆以及更好达意,全部用来表示控件的成员变量统一加上控件缩写做为后缀(文末附有缩写表)。

对于普通变量通常不添加类型后缀,若是统一添加类型后缀,请参考文末的缩写表。

用统一的量词经过在结尾处放置一个量词,就可建立更加统一的变量,它们更容易理解,也更容易搜索。

注意:若是项目中使用ButterKnife,则不添加m前缀,以lowerCamelCase风格命名。

例如,请使用mCustomerStrFirstmCustomerStrLast,而不要使用mFirstCustomerStrmLastCustomerStr

量词列表 量词后缀说明
First 一组变量中的第一个
Last 一组变量中的最后一个
Next 一组变量中的下一个变量
Prev 一组变量中的上一个
Cur 一组变量中的当前变量

说明:

集合添加以下后缀:List、Map、Set
数组添加以下后缀:Arr

注意:全部的VO(值对象)统一采用标准的lowerCamelCase风格编写,全部的DTO(数据传输对象)就按照接口文档中定义的字段名编写。

3.6 参数名

参数名以lowerCamelCase风格编写。
参数应该避免用单个字符命名。

3.7 局部变量名

局部变量名以lowerCamelCase风格编写,比起其它类型的名称,局部变量名能够有更为宽松的缩写。

虽然缩写更宽松,但仍是要避免用单字符进行命名,除了临时变量和循环变量。

即便局部变量是final和不可改变的,也不该该把它示为常量,天然也不能用常量的规则去命名它。

3.8 临时变量

临时变量一般被取名为ijkmn,它们通常用于整型;cde,它们通常用于字符型。 如:for (int i = 0; i < len ; i++)

3.9 类型变量名

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

  1. 单个的大写字母,后面能够跟一个数字(如:ETXT2)。
  2. 以类命名方式(参考3.2 类名),后面加个大写的T(如:RequestTFooBarT)。

更多还可参考~阿里巴巴Java开发手册

4 资源文件规范

4.1 资源布局文件(XML文件(layout布局文件))

所有小写,采用下划线命名法

4.1.1 contentView命名

必须以所有单词小写,单词间如下划线分割,使用名词或名词词组。

全部Activity或Fragment的contentView必须与其类名对应,对应规则为:将全部字母都转为小写,将类型和功能调换(也就是后缀变前缀)。

例如:activity_main.xml

4.1.2 Dialog命名

规则:dialog_描述.xml

例如:dialog_hint.xml

4.1.3 PopupWindow命名

规则:ppw_描述.xml

例如:ppw_info.xml

4.1.4 列表项命名

规则:item_描述.xml

例如:item_city.xml

4.1.5 包含项命名

规则:模块_(位置)描述.xml

例如:activity_main_head.xmlactivity_main_bottom.xml

注意:通用的包含项命名采用:项目名称缩写_描述.xml

例如:xxxx_title.xml

4.2 资源文件(图片drawable文件夹下)

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

命名模式:可加后缀 _small 表示小图, _big 表示大图,逻辑名称可由多个单词加下划线组成,采用如下规则:

  • 用途_模块名_逻辑名称
  • 用途_模块名_颜色
  • 用途_逻辑名称
  • 用途_颜色

说明:用途也指控件类型(具体见附录UI控件缩写表

例如:

名称 说明
btn_main_home.png 按键用途_模块名_逻辑名称
divider_maket_white.png 分割线用途_模块名_颜色
ic_edit.png 图标用途_逻辑名称
bg_main.png 背景用途_逻辑名称
btn_red.png 红色按键用途_颜色
btn_red_big.png 红色大按键用途_颜色
ic_head_small.png 小头像用途_逻辑名称
bg_input.png 输入框背景用途_逻辑名称
divider_white.png 白色分割线用途_颜色
bg_main_head 主模块头部背景图片用途_模块名_逻辑名称
def_search_cell 默认搜索界面单元图片用途_模块名_逻辑名称
ic_more_help 更多帮助图标用途_逻辑名称
divider_list_line 列表分割线用途_逻辑名称
selector_search_ok 搜索界面确认选择器用途_模块名_逻辑名称
shape_music_ring 音乐界面环形形状用途_模块名_逻辑名称

若是有多种形态,如按钮选择器:btn_xx.xml(selector)

名称 说明
btn_xx 按钮图片使用btn_总体效果(selector)
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

注意:使用AndroidStudio的插件SelectorChapek能够快速生成selector,前提是命名要规范。

4.3 动画文件(anim文件夹下)

所有小写,采用下划线命名法,加前缀区分。

具体动画采用如下规则:模块名_逻辑名称

例如:refresh_progress.xmlmarket_cart_add.xmlmarket_cart_remove.xml

普通的tween动画采用以下表格中的命名方式:动画类型_方向

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

4.4 values中name命名

4.4.1 colors.xml

colorsname命名使用下划线命名法,在你的colors.xml文件中应该只是映射颜色的名称一个ARGB值,而没有其它的。不要使用它为不一样的按钮来定义ARGB值。

不要这样作

<resources> <color name="button_foreground">#FFFFFF</color> <color name="button_background">#2A91BD</color> <color name="comment_background_inactive">#5F5F5F</color> <color name="comment_background_active">#939393</color> <color name="comment_foreground">#FFFFFF</color> <color name="comment_foreground_important">#FF9D2F</color> ... <color name="comment_shadow">#323232</color>

使用这种格式,你会很是容易的开始重复定义ARGB值,这使若是须要改变基本色变的很复杂。同时,这些定义是跟一些环境关联起来的,如button或者comment, 应该放到一个按钮风格中,而不是在color.xml文件中。

相反,这样作

<resources> <!-- grayscale --> <color name="white" >#FFFFFF</color> <color name="gray_light">#DBDBDB</color> <color name="gray" >#939393</color> <color name="gray_dark" >#5F5F5F</color> <color name="black" >#323232</color> <!-- basic colors --> <color name="green">#27D34D</color> <color name="blue">#2A91BD</color> <color name="orange">#FF9D2F</color> <color name="red">#FF432F</color> </resources>

向应用设计者那里要这个调色板,名称不须要跟"green""blue"等等相同。"brand_primary""brand_secondary""brand_negative"这样的名字也是彻底能够接受的。 像这样规范的颜色很容易修改或重构,会使应用一共使用了多少种不一样的颜色变得很是清晰。 一般一个具备审美价值的UI来讲,减小使用颜色的种类是很是重要的。

注意:若是某些颜色和主题有关,那就独立出去写。

4.4.2 dimens.xml

像对待colors.xml同样对待dimens.xml文件 与定义颜色调色板同样,你同时也应该定义一个空隙间隔和字体大小的“调色板”。 一个好的例子,以下所示:

<resources> <!-- font sizes --> <dimen name="font_larger">22sp</dimen> <dimen name="font_large">18sp</dimen> <dimen name="font_normal">15sp</dimen> <dimen name="font_small">12sp</dimen> <!-- typical spacing between two views --> <dimen name="spacing_huge">40dp</dimen> <dimen name="spacing_large">24dp</dimen> <dimen name="spacing_normal">14dp</dimen> <dimen name="spacing_small">10dp</dimen> <dimen name="spacing_tiny">4dp</dimen> <!-- typical sizes of views --> <dimen name="button_height_tall">60dp</dimen> <dimen name="button_height_normal">40dp</dimen> <dimen name="button_height_short">32dp</dimen> </resources>

布局时在写marginspaddings时,你应该使用spacing_xxxx尺寸格式来布局,而不是像对待string字符串同样直接写值。 这样写会很是有感受,会使组织和改变风格或布局是很是容易。

4.4.3 strings.xml

stringsname命名使用下划线命名法,采用如下规则:模块名+逻辑名称,这样方便同一个界面的全部string都放到一块儿,方便查找。

名称 说明
main_menu_about 主菜单按键文字
friend_title 好友模块标题栏
friend_dialog_del 好友删除提示
login_check_email 登陆验证
dialog_title 弹出框标题
button_ok 确认键
loading 加载文字
4.4.4 styles.xml

stylename命名使用大驼峰命名法,几乎每一个项目都须要适当的使用style文件,由于对于一个视图来讲有一个重复的外观是很常见的,将全部的外观细节属性(colorspaddingfont)放在style文件中。 在应用中对于大多数文本内容,最起码你应该有一个通用的style文件,例如:

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

应用到TextView中:

<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/price" style="@style/ContentText" />

你或许须要为按钮控件作一样的事情,不要中止在那里。将一组相关的和重复android:****的属性放到一个通用的style中。

将一个大的style文件分割成多个文件, 你能够有多个styles.xml 文件。Android SDK支持其它文件,styles这个文件名称并无做用,起做用的是在文件 里xml的<style>标签。所以你能够有多个style文件styles.xmlstyle_home.xmlstyle_item_details.xmlstyles_forms.xml。 不一样于资源文件路径须要为系统构建起的有意义,在res/values目录下的文件能够任意命名。

4.5 layout中的id命名

命名模式为:view缩写_模块名_逻辑名,好比btn_main_search
使用AndroidStudio的插件ButterKnife Zelezny,生成注解很是方便,原生的话可使用Android Code Generator插件。

若是想对资源文件进行分包能够参考我这篇文章~Android Studio下对资源进行分包

5 版本统一规范

Android开发存在着众多版本的不一样,好比compileSdkVersionminSdkVersiontargetSdkVersion以及项目中依赖第三方库的版本,不一样的module及不一样的开发人员都有不一样的版本,因此须要一个统一版本规范的文件。

具体能够参考我写的这篇博文~Android开发之版本统一规范

6 第三方库规范

别再闭门造车了,用用最新最火的技术吧,安利一波~Android 流行框架查速表,顺便带上本身的干货~Android开发人员不得不收集的代码

但愿Team能用时下较新的技术,对开源库的选取,通常都须要选择比较稳定的版本,做者在维护的项目,要考虑做者对issue的解决,以及开发者的知名度等各方面。选取以后,必定的封装是必要的。

我的推荐Team可以使用以下优秀轮子:

7 注释规范

为了减小他人阅读你代码的痛苦值,请在关键地方作好注释。

7.1 类注释

每一个类完成后应该有做者姓名和联系方式的注释,对本身的代码负责。

/** * <pre> * author : Blankj * e-mail : xxx@xx * time : 2017/03/07 * desc : xxxx描述 * version: 1.0 * </pre> */ public class WelcomeActivity { ... }

具体能够在AS中本身配制,Settings → Editor → File and Code Templates → Includes → File Header,输入

/** * <pre> * author : ${USER} * e-mail : xxx@xx * time : ${YEAR}/${MONTH}/${DAY} * desc : * version: 1.0 * </pre> */

这样即可在每次新建类的时候自动加上该头注释。

7.2 方法注释

每个成员方法(包括自定义成员方法、覆盖方法、属性方法)的方法头都必须作方法头注释,在方法前一行输入/** + 回车或者设置Fix doc comment(Settings → Keymap → Fix doc comment)快捷键,AS便会帮你生成模板,咱们只须要补全参数便可,以下所示。

/** * bitmap转byteArr * * @param bitmap bitmap对象 * @param format 格式 * @return 字节数组 */ public static byte[] bitmap2Bytes(Bitmap bitmap, CompressFormat format) { if (bitmap == null) return null; ByteArrayOutputStream baos = new ByteArrayOutputStream(); bitmap.compress(format, 100, baos); return baos.toByteArray(); }

7.3 块注释

块注释与其周围的代码在同一缩进级别。它们能够是/* ... */风格,也能够是// ...风格(//后最好带一个空格)。对于多行的/* ... */注释,后续行必须从*开始, 而且与前一行的*对齐。如下示例注释都是OK的。

/* * This is // And so /* Or you can * okay. // is this. * even do this. */ */

注释不要封闭在由星号或其它字符绘制的框架里。

Tip:在写多行注释时,若是你但愿在必要时能从新换行(即注释像段落风格同样),那么使用/* ... */

7.4 其余一些注释

AS已帮你集成了一些注释模板,咱们只须要直接使用便可,在代码中输入todofixme等这些注释模板,回车后便会出现以下注释

// TODO: 17/3/14 须要实现,但目前还未实现的功能的说明 // FIXME: 17/3/14 须要修正,甚至代码是错误的,不能工做,须要修复的说明

8 测试规范

业务开发完成以后,开发人员作单元测试,单元测试完成以后,保证单元测试所有经过同时单元测试代码覆盖率达到必定程度(这个须要开发和测试约定,理论上越高越好),开发提测。

// TODO...

9 RN规范

// TODO...

10 其余的一些规范

  1. 合理布局,有效运用<merge><ViewStub><include>标签;
  2. ActivityFragment里面有许多重复的操做以及操做步骤,因此咱们都须要提供一个BaseActivityBaseFragment,让全部的ActivityFragment都继承这个基类。
  3. 方法基本上都按照调用的前后顺序在各自区块中排列;
  4. 相关功能做为小区块放在一块儿(或者封装掉);
  5. 当一个类有多个构造函数,或是多个同名方法,这些函数/方法应该按顺序出如今一块儿,中间不要放进其它函数/方法;
  6. 数据提供统一的入口。不管是在 MVP、MVC 仍是 MVVM 中,提供一个统一的数据入口,均可以让代码变得更加易于维护。好比可以使用一个DataManager,把 httppreferenceeventpostdatabase 都放在DataManger里面进行操做,咱们只须要与DataManger打交道;
  7. 多用组合, 少用继承;
  8. 提取方法, 去除重复代码。对于必要的工具类抽取也很重要,这在之后的项目中是能够重用的。
  9. 可引入 Dagger2 减小模块之间的耦合性。Dagger2 是一个依赖注入框架,使用代码自动生成建立依赖关系须要的代码。减小不少模板化的代码,更易于测试,下降耦合,建立可复用可互换的模块;
  10. 项目引入RxJava + RxAndroid这些响应式编程,能够极大的减小逻辑代码;
  11. 经过引入事件总线,如:EventBusAndroidEventBusRxBus,它容许咱们在DataLayer中发送事件,以便ViewLayer中的多个组件都可以订阅到这些事件,减小回调;
  12. 尽量使用局部变量;
  13. 及时关闭流;
  14. 尽可能减小对变量的重复计算;

    以下面的操做:

    for (int i = 0; i < list.size(); i++) { ... }

    建议替换为:

    for (int i = 0, int length = list.size(); i < length; i++) { ... }
  15. 尽可能采用懒加载的策略,即在须要的时候才建立;

    例如:

    String str = "aaa"; if (i == 1) { list.add(str); }

    建议替换为:

    if (i == 1) { String str = "aaa"; list.add(str); }
  16. 不要在循环中使用try…catch…,应该把其放在最外层;

  17. 使用带缓冲的输入输出流进行IO操做;
  18. 尽可能使用HashMap、ArrayList、StringBuilder,除非线程安全须要,不然不推荐使用Hashtable、Vector、StringBuffer,后三者因为使用同步机制而致使了性能开销;
  19. 尽可能在合适的场合使用单例;

    使用单例能够减轻加载的负担、缩短加载的时间、提升加载的效率,但并非全部地方都适用于单例,简单来讲,单例主要适用于如下三个方面:

    (1)控制资源的使用,经过线程同步来控制资源的并发访问

    (2)控制实例的产生,以达到节约资源的目的

    (3)控制数据的共享,在不创建直接关联的条件下,让多个不相关的进程或线程之间实现通讯

  20. 把一个基本数据类型转为字符串,基本数据类型.toString()是最快的方式、String.valueOf(数据)次之、数据 + ""最慢;

  21. 使用AS自带的Lint来优化代码结构(什么,你不会?右键module、目录或者文件,选择Analyze → Inspect Code);
  22. 最后不要忘了内存泄漏的检测;

最后啰嗦几句:

  • 好的命名规则可以提升代码质量,使得新人加入项目的时候下降理解代码的难度;
  • 规矩终究是死的,适合团队的才是最好的;
  • 命名规范须要团队一块儿齐心合力来维护执行,在团队生活里,谁都不可能独善其身;
  • 一开始可能会有些不习惯,锲而不舍,总会成功的。

附录

UI控件缩写表

名称 缩写
TextView tv
EditText et
ImageButton ib
Button btn
ImageView iv
ListView lv
GridView gv
ProgressBar pb
SeekBar sb
RadioButtion rb
CheckBox cb
ScrollView sv
LinearLayout ll
FrameLayout fl
RelativeLayout rl
RecyclerView rv
WebView wv
VideoView vv
Spinner spn
ToggleButton tb

常见的英文单词缩写表

名称 缩写
icon ic (主要用在app的图标)
color cl(主要用于颜色值)
average avg
background bg(主要用于布局和子布局的背景)
buffer buf
control ctrl
default def
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)

程序中使用单词缩写原则:不要用缩写,除非该缩写是约定俗成的。

参考

Android 开发最佳实践

Android 编码规范

阿里巴巴Java开发手册

Google Java编程风格指南

小细节,大用途,35 个 Java 代码性能优化总结!

相关文章
相关标签/搜索