一份小组协同开发可以使用的 Android 代码规范
Braylen559
8年前
<h2>Chuxin Android Coding Style & 以前在公司的代码规范,可在组内推行</h2> <h2>1 Project structure 工程结构</h2> <p>1.1 Notice 说明</p> <p>New projects should follow the Android Gradle project structure that is defined on the Android Gradle plugin user guide . The BoilerPlate project is a good reference.</p> <p>新建工程需要按照最新的Android Gradle的工程结构,在以下定义: Android Gradle plugin user guide . 该工程: BoilerPlate 是一个很好的参考材料</p> <p>1.2 Resources directory structure 资源文件夹结构</p> <ul> <li>res <ul> <li>anim</li> <li>drawable (xml or selector)</li> <li>mipmap (pixel image)</li> <li>layout</li> <li>values</li> </ul> </li> </ul> <h2>2 Package Manner 包管理规范</h2> <p>2.1 General 通用</p> <ul> <li>package name : com.chuxin.[project name]</li> </ul> <p>2.2 App 包结构</p> <pre> <code class="language-java">* app * (class) Constant [后续有文件说明] * (class) Application * ui * fragment * activity * base * dialog * adapter * custom * service * (which servie) ... * entity * local * remote * manager * (which manager) ... * util * (which util)...</code></pre> <h2>3 File Naming 文件命名</h2> <p>3.1 Class files 类文件命名</p> <p>Class names are written in UpperCamelCase .</p> <p>For classes that extend an Android component, the name of the class should end with the name of the component; for example: SignInActivity , SignInFragment , ImageUploaderService , ChangePasswordDialog .</p> <p>For utilties class , the name of the class should start with its usage , and ends with Utils ; for example: HttpUtils , ImageUtils</p> <p>类命名方式采用 大驼峰 命名法</p> <p>对于继承自安卓组件的类来说,类名应该以该组件名结尾,例如 : SignInActivity , SignInFragment , ImageUploaderService , ChangePasswordDialog .</p> <p>对于工具类来说,命名方式应该以其完成功能开始,以 Utils 结束 ,例如 : HttpUtils , ImageUtils .</p> <p>3.2 Resources files 资源文件</p> <p>Resources file names are written in <strong>lowercase_underscore</strong> .</p> <p>资源文件以__小写加下划线__的方式命名</p> <p>3.3 Drawable files</p> <ul> <li>Naming conventions for drawables:</li> </ul> <p>drawable 文件的命名规范</p> <table> <thead> <tr> <th>Asset Type</th> <th>Prefix 前缀</th> <th>Example</th> </tr> </thead> <tbody> <tr> <td>Action bar</td> <td>ab_</td> <td>ab_stacked.9.png</td> </tr> <tr> <td>Button</td> <td>btn_</td> <td>btn_send_pressed.9.png</td> </tr> <tr> <td>Dialog</td> <td>dialog_</td> <td>dialog_top.9.png</td> </tr> <tr> <td>Divider</td> <td>divider_</td> <td>divider_horizontal.9.png</td> </tr> <tr> <td>Icon</td> <td>ic_</td> <td>ic_star.png</td> </tr> <tr> <td>Menu</td> <td>menu_</td> <td>menu_submenu_bg.9.png</td> </tr> <tr> <td>Notification</td> <td>notification_</td> <td>notification_bg.9.png</td> </tr> <tr> <td>Tabs</td> <td>tab_</td> <td>tab_pressed.9.png</td> </tr> </tbody> </table> <ul> <li>Naming conventions for icons:</li> </ul> <p>icons文件的命名规范</p> <table> <thead> <tr> <th>Asset Type</th> <th>Prefix 前缀</th> <th>Example</th> </tr> </thead> <tbody> <tr> <td>Icons</td> <td>ic_</td> <td>ic_star.png</td> </tr> <tr> <td>Launcher icons</td> <td>ic_launcher</td> <td>ic_launcher_calendar.png</td> </tr> <tr> <td>Menu icons and Action Bar icons</td> <td>ic_menu</td> <td>ic_menu_archive.png</td> </tr> <tr> <td>Status bar icons</td> <td>ic_stat_notify</td> <td>ic_stat_notify_msg.png</td> </tr> <tr> <td>Tab icons</td> <td>ic_tab</td> <td>ic_tab_recent.png</td> </tr> <tr> <td>Dialog icons</td> <td>ic_dialog</td> <td>ic_dialog_info.png</td> </tr> </tbody> </table> <ul> <li>Naming conventions for selector states:</li> </ul> <p>选择器状态文件的命名规范</p> <table> <thead> <tr> <th>State</th> <th>Suffix 尾缀</th> <th>Example</th> </tr> </thead> <tbody> <tr> <td>Normal</td> <td>_normal</td> <td>btn_order_normal.9.png</td> </tr> <tr> <td>Pressed</td> <td>_pressed</td> <td>btn_order_pressed.9.png</td> </tr> <tr> <td>Focused</td> <td>_focused</td> <td>btn_order_focused.9.png</td> </tr> <tr> <td>Disabled</td> <td>_disabled</td> <td>btn_order_disabled.9.png</td> </tr> <tr> <td>Selected</td> <td>_selected</td> <td>btn_order_selected.9.png</td> </tr> </tbody> </table> <p>3.4 Layout files 布局文件</p> <p>Layout files should match the name of the Android components that they are intended for but moving the top level component name to the beginning. For example, if we are creating a layout for the SignInActivity , the name of the layout file should be activity_sign_in.xml .</p> <p>布局文件的命名需要与他所嵌入的安卓组件匹配,但是将组件名称前移到开始处,例如,我们要创建一个名字为 SignInActivity , 其名字应该为 activity_sign_in.xml .</p> <table> <thead> <tr> <th>Component 组件</th> <th>Class Name</th> <th>Layout Name</th> </tr> </thead> <tbody> <tr> <td>Activity</td> <td>UserProfileActivity</td> <td>activity_user_profile.xml</td> </tr> <tr> <td>Fragment</td> <td>SignUpFragment</td> <td>fragment_sign_up.xml</td> </tr> <tr> <td>Dialog</td> <td>ChangePasswordDialog</td> <td>dialog_change_password.xml</td> </tr> <tr> <td>AdapterView Item</td> <td>---</td> <td>item_person.xml</td> </tr> </tbody> </table> <h2>4 Inside Code Naming 代码内部命名</h2> <pre> <code class="language-java">Important : 请不要使用拼音以及数字!!! ====== 常用缩写 ====== 完整单词 缩写 A average ——> avg B back ——> bk background ——> bg break ——> brk buffer ——> buf C color ——> cr(clr) control ——> ctrl D data ——> dat delete ——> del document ——> doc E edit ——> edt error ——> err escape ——> esc F flag ——> flg form ——> frm G grid ——> grd I increment ——> inc information ——> info initial ——> init insert ——> ins image ——> img L label ——> lab length ——> len list ——> lst library ——> lib M manager ——> mngr(mgr) message ——> msg O Oracle ——> Ora P panorama ——> pano password ——> pwd picture ——> pic point ——> pt position ——> pos print ——> prn program ——> prg S server ——> srv source ——> src statistic ——> stat string ——> str Sybase ——> Syb T temp ——> tmp text ——> txt U user ——> usr W window ——> wnd(win)</code></pre> <p>4.1 Class Variable Naming 类变量命名</p> <ul> <li>公有变量按 小驼峰 法命名</li> <li>私有 & 非静态成员变量以 m 开头</li> <li>私有 & 静态成员变量以 s 开头</li> <li>常量以大写字母和下划线 _ 组成</li> <li>尽量使用 功能/描述 + 类型 的模式 ,如 mNameTextView</li> <li>类中变量的组件类型请不要使用缩写</li> <li>注意不要使用 aa bb cc3 这种变态的命名方式 !!</li> <li>类变量过多时请 分块摆放 并且 写好注释</li> <li>接口类 请直接定义在类的最后</li> </ul> <p>Example:</p> <pre> <code class="language-java">public class MyClass { //静态常量 public static final int SOME_CONSTANT = 42; //公有变量 public int publicField; //私有静态变量 private static MyClass sSingleton; //默认变量 int mPackagePrivate; //私有变量 private int mPrivate; //继承型变量 protected int mProtected; }</code></pre> <p>4.2 Class Method Naming 类方法命名</p> <ul> <li>类方法采用 小驼峰 命名法</li> <li>根据函数所完成功能命名 , 如 changView()</li> <li>在函数头写对于函数功能、参数和返回值的注释,如:</li> </ul> <pre> <code class="language-java">/** * 获取两个数中最大的一个 * * @param value1 参与比较的第一个数 * @param value2 参与比较的第二个数 * @return 两个参数中最大的一个数 */ public int max(int value1, int value2) { return (value1 > value2) ? value1 : value2; }</code></pre> <ul> <li>一个函数请尽量保持在 50行 之内 !!</li> </ul> <p>4.3 layout.xml 布局文件变量命名</p> <ul> <li>id 以 所在组件_类型_命名 的模式,例如: @+id/main_tv_name 、 @id/chat_btn_send</li> <li>布局多处重用的请使用 <include> 标签</li> <li>所有文本请定义在 strings.xml 中 , 如 @string/app_name</li> <li>重用dp请定义在 dimens.xml 中 , 如 @dimen/entry_item_height</li> <li>对应组件缩写表:</li> </ul> <table> <thead> <tr> <th>Component 组件</th> <th>Abbreviation 缩写</th> </tr> </thead> <tbody> <tr> <td>Fragment</td> <td>fgm</td> </tr> <tr> <td>TextView</td> <td>tv</td> </tr> <tr> <td>ImageView</td> <td>iv</td> </tr> <tr> <td>Button</td> <td>btn</td> </tr> <tr> <td>EditText</td> <td>et</td> </tr> <tr> <td>LinearLayout</td> <td>ll</td> </tr> <tr> <td>ReleativeLayout</td> <td>rl</td> </tr> <tr> <td>normally : FirstSecond</td> <td>fs</td> </tr> </tbody> </table> <p>4.4 strings.xml dimens.xml colors.xml xml变量命名</p> <ul> <li>遵循 完整性 规范性 有序性 原则</li> </ul> <ul> <li><strong>分块并注释</strong> , 将 使用在不同的 Activity 或者 Fragment 中的 xml 变量 进行分块</li> <li>命名举例 : login_error_tips <strong>in</strong> strings.xml<br> login_error_tips_height <strong>in</strong> dimens.xml login_error_tips_bg <strong>in</strong> colors.xml</li> </ul> <table> <thead> <tr> <th>Prefix 前缀</th> <th>Description 描述</th> </tr> </thead> <tbody> <tr> <td>error_</td> <td>An error message</td> </tr> <tr> <td>msg_</td> <td>A regular information message</td> </tr> <tr> <td>title_</td> <td>A title, i.e. a dialog title</td> </tr> <tr> <td>action_</td> <td>An action such as "Save" or "Create"</td> </tr> </tbody> </table> <p>4.5 额外注意</p> <table> <thead> <tr> <th>Good</th> <th>Bad</th> </tr> </thead> <tbody> <tr> <td>XmlHttpRequest</td> <td>XMLHTTPRequest</td> </tr> <tr> <td>getCustomerId</td> <td>getCustomerID</td> </tr> <tr> <td>String url</td> <td>String URL</td> </tr> <tr> <td>long id</td> <td>long ID</td> </tr> </tbody> </table> <h2>5 Code Manner 代码规范</h2> <p>This is <strong>good</strong></p> <pre> <code class="language-java">if (condition){ body(); }</code></pre> <p>This is <strong>bad</strong> :</p> <pre> <code class="language-java">if (condition) body(); // bad!</code></pre> <p>This is <strong>good</strong> :</p> <pre> <code class="language-java"><TextView android:id="@+id/text_view_profile" android:layout_width="wrap_content" android:layout_height="wrap_content" /></code></pre> <p>This is <strong>bad</strong> :</p> <pre> <code class="language-java"><!-- Don't do this! --> <TextView android:id="@+id/text_view_profile" android:layout_width="wrap_content" android:layout_height="wrap_content" > </TextView></code></pre> <h2>6 Constant 内部类解析</h2> <ul> <li>Constant * CODE --> request_code , app_key 等 * CONFIG --> 项目的配置变量, 偏向于调试开发使用,如: IS_DEBUG , SHOW_LOG * URL --> 网络地址相关 * COUNT --> 某些约定的数字,如一次刷新显示的条目数量。 <strong>一定要有注释</strong> * PATH --> 路径信息,SD卡路径等 * KEY --> 键值对的键的信息,如 Bundle 中的键</li> </ul> <h2>7 Git 提交规范</h2> <p>基本要求</p> <ul> <li>分段</li> </ul> <p>例子:</p> <pre> <code class="language-java">(Git test) Modify CircleImageView to show rounded rectangle https://trello.com/c/M7u5h0QA The original function can be used normally, To show rounded rectangle, you need add param "bao:round" to XML file, it's value is the rounded rectangle's corner radius.</code></pre> <p>第一行: 作为标题,这在 Git 中就会做为默认显示的部分,如图中深黑色字: <img src="https://simg.open-open.com/show/2646f9f2464d6778c1a0fa0fef5ec4fd.png"></p> <p>第二行: 留空!因为通常在设置了邮件提醒的 Git 系统中,第二行的空行是作为分隔标题和正文的存在。</p> <p>第三行: 开始就是详细说明了。可以加上对此次修改的问题的链接,或者描述。如果有用到 issue 的话可以写上 issue #[issue id] ,或者附上 <strong>trello</strong> 的链接。</p> <p>建议全部用英文写,其他字符有乱码的可能。</p> <p>并不会乱码</p> <ul> <li>粒度</li> </ul> <p>说的是做的修改的粒度。如果你一天做了很多的修改,但是就只提交了一次,那么你的粒度就有点大了。</p> <p>这样在你描述你的行为的时候就会显得模糊,如果你详细描述的话,提交信息会变得长篇大论。</p> <p>但也不要做一点提交一点,这样粒度就会变得太小,会导致一天到晚在写提交信息,没有必要。</p> <p>在我看来,这个事情真的只能凭感觉提交,用经验来做判断。因为一个BUG可能可大可小,大的话,你就得分割修复。</p> <p>如果小,那么就一次提交修复就可。</p> <p>粒度的掌握绝对会影响你的提交信息,因为二者是一一对应的。</p> <ul> <li>宽度</li> </ul> <p>是的,是宽度,不是长度。</p> <p>和代码一样,如果你平时注意的话,就不要让你的代码在一行上超过80,不然谁读代码都不好受,包括你自己。</p> <p>所以提交信息的宽度也有限制。</p> <p>分别是标题不要超过50,内容部分不要超过70。</p> <p>大概大家都会的没什么用的小Tips:</p> <ul> <li>使用 git commit 命令并进入 Vim 编辑提交信息,写完后按 Esc 确保不在编辑状态,然后输入 :wq 回车退出并提交。</li> <li>直接使用 Android Studio 自带的 VCS 也很方便。</li> </ul> <p>参考资料:</p> <ul> <li><a href="/misc/goto?guid=4959742873480581197" rel="nofollow,noindex">Git - 如何写好你的提交信息?</a></li> <li><a href="/misc/goto?guid=4959742873572443013" rel="nofollow,noindex">写出好的 commit message</a></li> </ul> <p> </p> <p>项目主页:<a href="http://www.open-open.com/lib/view/home/1490252199221">http://www.open-open.com/lib/view/home/1490252199221</a></p> <p> </p>