百度android代码命名规范

代码规范

1.     简介

A.    目的

本文提供一整套编写高效可靠的 Java 代码的标准、约定和指南。它们以安全可靠的软件工程原则为基础,使代码易于理解、维护和增强。而且,通过遵循这些程序设计标准,你作为一个 Java 软件开发者的生产效率会有显著提高。经验证明,若从一开始就花时间编写高质量的代码,则在软件开发阶段,对代码的修改要容易很多。最后,遵循一套通用的程序设计标准将带来更大的一致性,使软件开发团队的效率明显提高。

        

Note: 规范编码的目的是让开发者更容易理解其他人的代码,而不是约束你编码的方式

B.    范围

本指南仅适用于使用Java编写的 Android 程序代码。

C.    参考资料

http://www.oracle.com/technetwork/java/codeconvtoc-136057.html

http://source.android.com/source/code-style.html

《LeOS开发规范v1.2.doc》

 


 

2.     快速入门

l  驼峰式命名(大小写交替)

错误:

public class myClass

public interface foo

public final static int max = 100

public int FooValue

正确:

public class MyClass

public interface IFoo

public final static int MAX = 100

public int fooValue

l  使用Javadoc识别的注释

在函数声明前添加注释(输入”/**”+回车)

l  精简函数体(最好不要超过40行)

l  局部变量随用随声明(尽量缩小变量的作用域)

l  每行最长100字符

l  缩进用4个空格代替TAB

l  private变量名用m开头

l  多用大括号

l  前大括号”{“不要单占一行

错误:

if (condition)

{

//do something

    }

正确:

if (condition) {

    //do something

}

l  尽可能多的处理异常(不要只catch不处理)

l  多利用标准注解

错误:

public void onCreate(Bundle savedInstanceState) {

正确:

@Override

public void onCreate(Bundle savedInstanceState) {

l  少用不常见缩写

错误:opnDlg

正确: openDialog

3.     命名

基本 Java 命名规范

命名应符合驼峰式规则,利用大小写字母交替来区分名称中的不同单词,即应采用小写字母,但类名、接口名以及任何非初始单词的第一个字母要大写。

 

1.        尽量使用完整的英文描述符,采用适用于该领域的术语

2.        采用大小写混合使名字可读

3.        尽量少用缩写,但如果用了,要明智地使用。

4.        避免使用长的名字(小于 15 个字母是个好主意)

5.        避免使用类似的名字,或者仅仅是大小写不同的名字

类型

规则

示例

包名

全部小写字母,URL倒序

package com.baidu.dubicycle

类名

首字母大写,使用描述性强的名词,避免使用缩写,除非该缩写十分通用(Url、Html)

class Raster;

class ImageSprite;

接口

同上

interface RasterDelegate;

interface Storing;

方法

使用动词,驼峰式命名,首字母小写

run();

runFast();

getBackground();

变量

使用有意义的简短的单词,驼峰式,首字母小写,临时变量一般int型使用i,j,k,m,n; char型使用c,d,e

Private protected变量m开头

static变量s开头

int i;

float myWidth;

private int mPrivate;

protected int mProtected;

private static MyClass sSingleton;

常量

全部大写,用下划线分割单词

int MIN_WIDTH = 4;

int MAX_WIDTH = 999;

int GET_THE_CPU = 1;

 

Android 命名相关

Ø  Activity命名:xxxxActivity

Ø  View命名:xxxxView 或者 xxxxLayout

Ø  Service命名:xxxxService

Ø  BroadcastReceiver命名:xxxxReceiver

Ø  Layout文件命名:

Activity的Content View应使用:act_xxxx.xml的形式

自定义View应使用:vw_xxxx.xml

 

Android 资源文件命名

Ø  文件名全部小写,单词之间使用下划线连接。例如:click_button.png。类似click_button.PNG 和 clickButton.png 等都是错误的形式

Ø  关于StateListDrawable各种状态的命名后缀:

xxxx_checked.png

xxxx_focused.png

xxxx_selected.png

xxxx_pressed.png

xxxx_disabled.png

xxxx_normal.png

相关的XML文件以 xxxx.xml 命名

Ø  常量文件的命名:

strings.xml

dimens.xml

drawables.xml

styles,xml

themes.xml

colors.xml

ids.xml

4.     声明

每行的数量

l  每行声明一个(方便添加注释)

错误:

int level, size;

正确:

int level; // indentation level

int size; // sizeof table

 

l  不同类型声明不要声明在同一行

错误:

int foo, fooArray[];

正确:

int foo;

int[] fooArray;

 

声明的时机

l  缩小局部变量的作用域

局部变量使用时在声明,声明时就进行初始化,如果声明时无法获得足够的信息初始化,考虑推迟声明变量的时机。

正确:

for(int i=0; i<0; i++)

错误:

int i;

//do something.....

for(i=0; i<0; i++)

 

例外:try-catch语句会破坏这条规则,因此这种情况下可以提前声明变量

// Instantiate class cl, which represents some sort of Set

Set s = null;

try {

    s = (Set) cl.newInstance();

} catch(IllegalAccessException e) {

    throw newIllegalArgumentException(cl + " not accessible");

} catch(InstantiationException e) {

    throw newIllegalArgumentException(cl + " not instantiable");

}

 

// Exercise the set

s.addAll(Arrays.asList(args));

 

 

 

5.     语句

每行的数量

l  一行一句

错误:

argv++; argc--;//

正确:

argv++;

argc--;

return语句

 

return简单值不要加括号

错误:

return (1);

正确:

return 1;

return (size ? size: defaultSize);

if,if-else, if-else-if-else 语句

不要省略大括弧

正确:

if(condition){

    statements;

}

if(condition){

    statements;

}else{

    statements;

}

if(condition){

    statements;

}else if(condition){

    statements;

}else if(condition){

    statements;

}

错误:

if (condition)//没有大括号

statement;

for 语句

不要省略大括弧

正确:

for(initialization;condition; update){

    statements;

}

在initialization中不要超过3个变量声明

while 语句

不要省略大括弧

正确:

while(condition){

    statements;

}

do-while 语句

不要省略大括弧

正确:

do{

    statements;

}while(condition);

switch 语句

l  不要省略大括弧

l  必须有default

l  没有break的case要加注释

l  default中最好也添加break语句(以免在后面添加case,造成错误)

switch(condition){

case ABC:

    statements;

    /*没有break,解释原因*/

case DEF:

    statements;

    break;

case XYZ:

    statements;

    break;

default:

    statements;

    break;

}

try-catch 语句

不要省略大括弧

正确:

try{

    statements;

}catch(ExceptionClass e){

    statements;

}

6.     缩写的使用

l  尽量少使用缩写,除非该缩写很常见(Html、Url)

l  把缩写当成一个普通单词,不要都大写

 

正确

错误

XmlHttpRequest

XMLHTTPRequest

getCustomerId

getCustomerID

class Html

class HTML

String url;

String URL;

long id;

long ID;

 

7.     缩进和空格

空格的使用

在代码中,’,’ ‘;’等标点后应有一个空格;’+’ ‘-‘‘*’等运算符前后均应有一个空格;其他符号如’.’ ‘(‘’)’ 等原则上不须空格。

空行的使用

在代码中逻辑性代码块的起始、结尾处,都应该加入空行,并在起始处写注释。

相对独立的程序块之间、变量说明之后必须加空行。

嵌套和缩进

在一个代码块中应该缩进,包括有:If/for/while 等语句;

在续行的代码中应缩进;

缩进取4格,使用Tab字符,Java中Tab应取4格;

注意:默认情况下,Eclipse不会在switch块中缩进,这个应该注意参考相关工程说明。

 

在eclipse中调整tab为空格的方法:

1)在Window > Preferences中找到Java > Code Style >Formatter

2)点击New,新建一份profile

3)设置Tab Policy

续行

较长的语句、表达式或参数(>100字符)要分成多行书写,长表达式要在低优先级操作符处划分新行,操作符放在新行之首,划分出的新行要进行适当的缩进,使排版整齐,语句可读。

例外:

1) import所在行可以超过100字符

2) 注释中含有url,为了方便复制或剪切,可以超过100字符

 

8.     大括号的使用

为了代码紧凑,前大括号不要单独占用一行

正确:

class Test {

  public void fun() {

      if (condition_0) {

         do some thing here;

     } else {

         do some thing here;

     }

   }

}

错误:

class Test

{

  public void fun()

{

     if (condition_0)

{

         do some thing here;

     } else {

         do some thing here;

      }

   }

}

 

 

9.     注释

注释要求

l  无论是用户端表示层程序还是组件程序,注释必不可少。

l  要求能占程序总量的10%以上。

l  注释必须在程序改变时实时更新。

l  简单明了,确保任何程序员都可以读懂。

l  注释一般应写在代码之前,并与代码分开不同的行;但对于说明变量含义的注释,一般应写在变量说明的同行的行末,并且在各行间保持对齐;

l  如果可能,尽量使用单行注释‘//’。

l  对于代码维护,应在过程或方法中记录相应修改的作者、时间,并在具体修改的位置用特殊的标签注明(标签一般应包含修改人的名字汉语拼音或拼音简写、日期戳和可选的修改项目名字)。

 

使用JavaDoc辅助生成统一的注释

为规范、方便生成统一的程序文档,应在代码注释中遵循JavaDoc的注释规范(建议在开发工具中输入“/**回车”,填入所有自动弹出项。

类约定注释与JavaDoc中对应

模块名称:  See

功能描述:  Todo

作者:      Author

版本:      Version

/**

 * 对系统规范化的异常处理。包含各种异常编码,标准出错提示与日志的产生和管理。

 *

 * 异常类型ID

 *  1-49  :系统内部异常 - 标准处理:写日志,向客户端抛出CustomException异常

 * 50-99  :用户界面异常 - 标准处理:写日志,向客户端抛出对应的自定义异常

 * 100以上:扩展异常

 *

 * 注意:写日志时应使用 getSysMsg() 获得对应的异常日志记录串;向用户端抛出的

 *       异常则在 getUserMsg() 中携带应在界面上显示的信息串

 *

 * @since 2001-12-18

 * @author lijun

 * @version 1.0

 *

 */

 

过程和方法约定注释与JavaDoc中对应

功能描述:       Method Comments

参数说明:       Parameter Comments

返回值说明:     Returns

最后更新作者:   如有改动,自己添加

最后更新日期:   如有改动,自己添加

   /**

     * 初始化方法,在这里初始化所有用户公用的变量,

     * 这里简单地将工作交给父类处理。

     * @param config ServletConfig对象,包含Servlet初始化的参数。

     * @throws ServletException 初始化可能产生ServletException异常。

     * @return

     */

 

Eclipse中设置注释格式

1) 在Window > Preferences中找到Java > Code Style >Code Templates

2) 双击要修改的类型,进行编辑

 

 

10.             注解

使用常用的注解可以使程序具有更好的可读性

@Deprecated

当函数,变量,类等不推荐使用,可以用@Deprecated注解,提示后续开发人员避免使用该代码

@Overide

当重载或实现父类(接口)的方法时,用Overide做注解。

@SuppressWarnings

当使用代码会产生编译器warning,同时可以保证该代码没有问题,使用SuppressWarnings注解,同时在前面加上TODO注释来解释原因。

例如:

// TODO: The third-party classcom.third.useful.Utility.rotate() needs generics

@SuppressWarnings("generic-cast")

List<String> blix =Utility.rotate(blax);

 

11.             异常处理

异常是我们的朋友,帮助我们定位潜在的错误,因此要小心的处理

不要忽略异常

错误:

void setServerPort(String value) {

   try {

       serverPort = Integer.parseInt(value);

    }catch (NumberFormatException e) { }

}

这段代码忽略了可能发生的异常,真正发生异常时,我们无法得到提示。

我们可以这样做(从最好到最差的解决方案)

1)把异常抛给调用者

void setServerPort(String value) throwsNumberFormatException {

   serverPort = Integer.parseInt(value);

}

 

2)抛出自定义类型异常

void setServerPort(String value) throwsConfigurationException {

   try {

       serverPort = Integer.parseInt(value);

    }catch (NumberFormatException e) {

       throw new ConfigurationException("Port " + value + " isnot valid.");

    }

}

 

3)尝试恢复错误

/** Set port. If value is not a validnumber, 80 is substituted. */

void setServerPort(String value) {

   try {

       serverPort = Integer.parseInt(value);

    }catch (NumberFormatException e) {

       serverPort = 80;  // default portfor server

    }

}

 

4)抛出RuntimeException让应用crash

/** Set port. If value is not a valid number,die. */

void setServerPort(String value) {

   try {

       serverPort = Integer.parseInt(value);

    }catch (NumberFormatException e) {

       throw new RuntimeException("port " + value " is invalid,", e);

    }

}

 

5)如果确实需要忽略异,添加注释来说明

/** If value is not a valid number,original port number is used. */

void setServerPort(String value) {

   try {

       serverPort = Integer.parseInt(value);

    }catch (NumberFormatException e) {

       // Method is documented to just ignore invalid user input.

        // serverPort will just be unchanged.

    }

}

 

不要只捕获通用异常

不要因为懒惰写出如下代码

try {

   someComplicatedIOFunction();       // may throw IOException

   someComplicatedParsingFunction();  // may throw ParsingException

   someComplicatedSecurityFunction(); // may throw SecurityException

    // phew, made it all theway

} catch (Exception e) {              // I'll just catch all exceptions

    handleError();                      // with one generichandler!

}

 

解释:任何异常都被catch住了,当出现问题时,我们的代码也不会抛出exceptio,从而无法有效定位错误。

12.             使用Log

l  充足的log可以便于定位错误

l  Log太多会影响程序性能(I/O耗时)

l  Log使用的黄金原则——不要把其他程序的log挤出缓存

l  Log.v()的输出不要包含到最后的产品中

l  应该设置开关控制是否开启Log.d()的输出信息

13.             和周围代码风格一致

编码时注意代码风格和周围尽量保持一致性. 如果周围的代码在if和后面的括号间使用空格,或者用小方框的方式包围一段注释,我们最好也要这么做。

14.             其他

不用finalizer

finalizer是object在被垃圾回收时执行的一段代码,用finalizer的好处是可以在一段代码里释放不需要的资源,但Google建议不要用finalizer。因为不能保证什么时候会调用finalize的代码,甚至不能保证是否会调用finalizer的代码。

 

可以对异常处理进行精心设计,在异常处理中释放资源。

 

使用短函数

当函数体长度超过40行,应考虑拆分成多个函数

import中不使用通配符

如果你需要从package foo中引入class Bar, 有以下两种方式

1.       import foo.*;

2.       import foo.Bar

在android中,请用第2种import方式。

 

类声明组织顺序

类属性和类方法不要交叉放置,不同存取范围的属性或者方法也尽量不要交叉放置。

格式:

类定义{

    类的公有属性定义

    类的保护属性定义

    类的私有属性定义

    类的公有方法定义

    类的保护方法定义

类的私有方法定义

 

*内部类定义

*接口、枚举定义

}

15.             性能和稳定性原则

避免内存泄露

原则1:及时回收Bitmap资源

对于在代码中创建出来的Bitmap资源,一定要在适当的时候通过Bitmap.recycle()予以销毁,系统不会对通过Bitmap.createBitmap方式创建出来的Bitmap进行回收。合理的时候比如在Activity::onDestroy()中销毁Bitmap.

示例:

 创建:

    Bitmap  mybitmap = Bitmap.createBitmap();

 回收:

    mybitmap.recycle();

 

原则2:register注册的响应函数,一定要有unRegister的时候

无论何时register注册的响应钩子,一定要有unRegister的时候,否则该引用不能被系统正确回收。

示例:

         publicvoid onCreate(){

         setCallback(mycallback);

                   registerReceiver(myReceiver);

}

 

public voidonStop(){

         setCallback(null);

         unRegisterReceiver(myReceiver);

}

Regiser注册的内容很多,请务必仔细,如contentObserver, Cursor, CallBack函数都是需要清理的对象。

 

 

原则3:使用Adapter时要尽量使用convertView缓存引用

在使用Adapter的时候,要尽量使用convertView缓存引用,以便节省内存空间。

示例:

View   Adapter::getView(View converView , int pos)

{

View v ;

if(convertView != null)  //如果converView存在,那么使用converView来作为创建出的View引用。

v = convertView;

else  //如果convertView不存在,则创建新的View引用。

v = makeNewView();

v.setData();//给View引用设置数据

return v;

}

原则4:从网络下载的数据和保存的临时文件要及时清理

原则5:内存使用不能超过上限

Rocket系统中,除特殊应用外,所有应用的内存上限是32M,超过这个上限应用程序就会崩溃,我们在设计UI和编写代码的时候应该警惕内存使用,尤其是图片加载。

避免出现系统超时无响应 (有时也表现为打开/关闭窗口刷新不正常)

在使用过程中,我们有时候会遇到界面无响应,弹出对话框询问是关闭进程还是继续等待,发生该异常的原因是应用主线程在某处阻塞,导致新的系统消息(如广播Intent, Key事件, Touch事件)不能正常处理,系统端迟迟收不到应用返回的消息已处理事件,从而判定应用无响应,弹出提示对话框。同时,长时间的阻塞主线程可能会导致WindowManagerService不能正确处理窗口切换刷新,引起打开/关闭Activity时出现刷新不正常。

 

发生异常时常见的Log有:

 Activitiy Idle timeout …

 Activity Launch timeout

 Service execute timeout

 Key dispatch timeout

 Broadcast Receiver Intent *** timeout

 

避免这个问题有以下几个原则。

原则1:需要时间很长的操作,须要单独启动新的线程执行

例如:

   搜索网络,Wifi

   网络访问

   加载/卸载Sd卡

   大量读写数据库

   读写较大文件(比如大尺寸的图片)

通常与底层数据读取相关的函数需要重点关注。

启动新线程要使用Thread.start()函数,而不是用Thread.run()函数。使用线程一定要注意synchronized同步以及资源回收。

 

原则2 使用Handler异步处理

对于结构不易另外开新线程的代码, 或者调用Binder与其它能够联系的代码 , 应该尽量避免在系统回调函数中直接运行,要通过sendMessage来异步调用,这样可以保证系统能够及时从应用获得消息处理完毕的事件。

例如:

startActivity() 打开Activity

startService()  打开Service

    sendBroadcast() 发Intent广播

    showDialog() 显示对话框

         耗时长的事件可能较多,需要大家实际分析,比如获取当前网络,硬件,电话等底层状态都可能会导致阻塞

 

错误:

 public void onCreate(){

sendBroadcast(testIntent);

  }

在onCreate回调函数中发送广播以及显示对话框,有可能会造成系统端阻塞

 

正确:

         publicint TEST_MSG = 0;

         publicHandler myHandler = new Handler(

                   publicvoid handleMessage(Message msg){

                            switch(msg.what){

                            caseTEST_MSG:

                                     sendBroadCast(myintent);

                                     break;

            default:

                break;

                            }

                   }

         };

 

         publicvoid onCreate(){

                   myHandler.sendMessage(myHandler.obtainMessage(TEST_MSG));

}

通过发送Message的方式来异步调用。

注意:发送Message只是将要执行的操作放到onCreate()回调函数之外去操作,并不是启动新线程进行,如果需要时间过长,同样可能引发阻塞。

 

 

原则3 使用Http连接需要加入超时时间限制

示例:

  HttpUrlConnection mHttpConnection = url;

  mHttpConnection.setConnectTimeout(5000 );

 

原则4 尽量避免使用System.exit(0)的方式来退出应用

         尽量避免使用System.exit(0)的方式来退出应用,尤其需要注意当有其它并发线程的时候,System.exit(0)可能会带来一系列风险。

         使用System.exit(0) . Process.killProcess会直接杀掉当前进程,而android中默认是不会关闭进程的,在杀掉当前进程的时候需要考虑并发线程的状态,例如如果并发线程当前正在读取文件,操作数据库,跨进程访问,这时关闭进程就会导致一系列问题甚至引起系统崩溃。

 

原则5 减少使用数据库的次数,避免频繁调用

目前数据库在使用过程中有偶然变慢甚至阻塞崩溃的可能性,因此在代码设计时一定要减少数据库的操作次数。

ListView使用优化

a. 避免在不同线程中同时刷新数据或是改变Adapter内容,或者改变Cursor内容的情况,在需要并发刷新的时候要用synchronized来同步,这样可以避免出现ListView崩溃。

   b. 使用convertView来减小内存开销

   c. 减少Adapter改变次数,每次Adapter都会带来ListView的重新刷新。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值