Android 编码规范

2016-03-17  本文已影响159人  Xiho丶

命名基本原则

分类命名规范

Activity:描述+Act
Fragment:描述+Frag
View:描述+View
Receiver:描述+Receiver
Service:描述+Service
请求bean:请求描述+Req
Integer:int+描述          Char:chr+描述          Boolean:bln+描述 
Long:lng+描述           Short:shr +描述         Double:dbl+描述
String:str+描述           Float:flt+描述          Single:sng+描述
DataTime:dt+描述         int[](数组):arr+描述        Object:obj+描述     
List:描述+List
局部变量:String  srtName;
全局变量 :  String mStrName; 如果是全局变量就在变量名加上m字母再将第二个单词首字母改为大写。
TextView 代码:txt+描述 ;XML id:txt_+描述 (下面不再详述) 全局变量:mTxt+描述,局部变量:txt+描述 (全局与局部的区别下面不再详述)
Button :btn+描述  ;
ImageButton :ib+描述
ImageView :img+描述
CheckBox :chk+描述
RadioButton :rb+描述
AnalogClock :ac+描述 
DigitalClock :dc+描述
DatePicker :dp+描述
TimePicker :tp+描述
ToggleButton :tb+描述
EditText:edit+描述
ProgressBar:pb+描述
SeekBar:sb+描述
AutoCompleteTextView:autotxt+描述
MultiAutoCompleteTextView:mlautotxt+描述 
ZoomControls:zc+描述
Include:ind+描述 
VideoView:vv+描述
WebView:wv+描述
RatingBar:ratbr+描述
Tab:tab+描述
Spinner:spin+描述
Chronometer:chro+描述
ScrollView:sv+描述
TextSwitcher:tswi+描述  
Gallery:gal+描述
ImageSwitcher:imgswi+描述
GridView:gv+描述
ListView:lv+描述
ExpandableList: exl+描述
MapView: mv+描述

注释

/* 
 * @Title:  ${file_name} 
 * @author:  tomcat
 * @data:  ${date} ${time} <创建时间>
 * 
 * @history:<以下是历史记录>
 *
 * @modifier: <修改人>
 * @modify date: ${date} ${time} <修改时间>
 * @log: <修改内容>
 *
 * @modifier: <修改人>
 * @modify date: ${date} ${time} <修改时间>
 * @log: <修改内容>
 */
/** 
 * ${todo}<请描述这个类是干什么的> 
 * @author  tomcat 
 * @versionCode 1 <每次修改提交前+1>
 */
/**  
 * public函数
 * ${todo}<请描述这个方法是干什么的> 
 * @param pos <参数说明>
 * @throw 
 * @return ${return_type} <返回值说明>
 */
public Object getItemByPos(int pos){
     .......
}
//<请描述这个方法是干什么的> 
private void create(){
    // 在函数中也可适当添加注释
}
private Context mContext; //上下文对象
private TextView txtTitle;   //标题
private int lastTouchX;      //最后手指按下时的X轴坐标
局部变量和逻辑块也要适当加上// 注释
public InputStream open(){
    String webUrl = "www.baidu.com"; //要连接的网址
    ......
    ......
}

编码规范

1 明确方法功能,精确实现方法设计,一个函数仅完成一个功能。
2 函数的调用者应该负责对参数的合法性检查,参数的合法性检查尽量不要放在函数中实现(视情况而定)

public Goods getGoodsByName(String name){
    if( TextUtils.isEmpty(name) ){
         return null;
    }
    ......
    ......
}
{
    Goods goods = getGoodsByName(name);
    if( goods == null ){
        return;
    }
    ......
    ......
}
X
{
    if( TextUtils.isEmpty(name) ){
         return;
    }
    Goods goods = getGoodsByName(name);
    ......
    ......
}
√

3 明确类的功能,精确(而非近似)地实现类的设计。一个类仅实现一组相近的功能。

划分类的时候,应该尽量把逻辑处理、数据和显示分类,实现类功能的单一性
比如:
数据类不能包含数据处理的逻辑,比如Bean实体
通信类不能包含显示处理的逻辑,比如Socket、DownloadManger

4 所有数据类必须重载toString()方法, 返回该类有意义的内容。

public TopoNode{
    private String nodeName;
    
    public String toString(){
        return  "NodeName : " + nodeName;
    }
}

5 数据库、IO操作等使用后需要close()的对象必须在try-catch-finally的finally中close().

try  
{  
      //   . . .   . . .  
}  
catch(IOException  ioe)  
{  
      // . . .   . . .  
}  
finally  
{  
        try  
        {  
             out.close( ) ;  
        }  
        catch(IOException  ioe)  
        {  
             // . . .   . . .  
        }  
}

6 避免使用不易理解的数字,用有意义的标识来替代。涉及物理状态或者有意义的数字,必须用有意思的静态常量来代替。所有switch case 的int值包括message的what值都必须有常量来描述并加上注释。
可读性差的代码:

switch (code) {
    case 1:
    ... ...
    break;
X
private final static int IDLE = 1; //空闲状态
switch (code) {
    case IDLE:
    ... ...
    break;
√

7 View的显示控制逻辑最好放在Controller中(使用MVC时)

8 Activity与Fragment中的代码不允许超过400行,最好控制在300行以内,超过400行代码的Activity意味着你的代码可能没有做任何封装和划分,是时候优化你的代码了。

9 所有超过20行的抽象实现类(或者匿名内部类)都必须抽出来单独实现再实例化,禁止运行时实现, 与执行过程无关的代码尽量不要放在执行过程中

重构前:
{
        testTimerTask=new TimerTask() {
            
            @Override
            public void run() {
                runOnUI(new Runnable() {
                    public void run() {

                        List<Integer> netData=NetworkStrengthController.getInstance(mContext).getNetData();
                        if(!netData.isEmpty()){
                            strength_now.setText("当前信号强度:"+netData.get(netData.size()-1)+"dB");
                            strength_max.setText("信号强度最高:"+Collections.max(netData)+"dB");
                            strength_low.setText("信号强度最低:"+Collections.min(netData)+"dB");
                            if(netStates.size()>0){
                                strength_base.setText("连接基站个数:"+netStates.size());
                            }
                            
                            //评级
                            if(netStates.size()>3){
                                strength_rate_iv.setImageResource(R.raw.netstrength_poor);
                            }else{
                                float sum=0;
                                for(float num: netData){
                                    sum=sum+num;
                                }
                                float avg=sum/netData.size();
                                if(avg>-60){
                                    strength_rate_iv.setImageResource(R.raw.netstrength_good);
                                }else if(avg>-90){
                                    strength_rate_iv.setImageResource(R.raw.netstrength_normal);
                                }else if(avg>-110){
                                    strength_rate_iv.setImageResource(R.raw.netstrength_poor2);
                                }else{
                                    strength_rate_iv.setImageResource(R.raw.netstrength_poor);
                                }
                            }
                        }
                    
                    }
                });
            }
        };
                testTimer.schedule(testTimerTask, 0, 1000);
}
XXX
重构后:
public class NetworkController{
     //注释
    public setStrengthNow(TextView tv){
        int now = getStrengthNow();
         tv.setText("当前信号强度:"+ now +"dB");
    }
    //注释
    public setStrengthMax(TextView tv){
        int max = getStrengthMax();
        tv.setText("信号强度最高:"+ max +"dB");
    }
    //注释
    public setStrengthLow(TextView tv){
        int low = getStrengthLow();
        tv.setText("信号强度最低:"+ low +"dB");
    }
    //显示信号强度评级
    public void setStrengthRate(ImageView iv){
        ... ... //计算评级
        ... ...//设置显示
    }
}
Activity代码:
Runnable runTest = new Runnable(){
     public void run() {
           boolean hasSignal = mNetworkController.hasSignal(); //是否检测到信号
           if(hasSignal){
                //显示信号强度
                mNetworkController.setStrengthNow(txtStrengthNow);
                mNetworkController.setStrengthMax(txtStrengthMax);
                mNetworkController.setStrengthLow(txtStrengthLow);
                .....
                //显示评级
                mNetworkController.setStrengthRate(ivStrengthRrate);
                
           }
     }
}
{
    testTimerTask=new TimerTask() {
            
    @Override
    public void run() {
        runOnUI(runTest);
    }
    };
    testTimer.schedule(testTimerTask, 0, 1000);
}
√√√

11 Activity与Service之间的通信只能使用广播或者Binder代理对象

12 ListView的Adapter的getView函数代码统一使用自定义View来封装(也就是每一种Item都是一类自定义View)

13 所有相似的Dialog弹出框逻辑都抽取到Utils中便于复用。

14 禁止直接new Thread()必须使用线程池启动线程。

15 逻辑复杂的一块UI应封装为自定义View,良好的Activity结构应该由多个自定义View组成,以减少Activity中的代码

16 布局能用一层就用一层尽量减少布局嵌套

17 注释的代码能删除就删除不要留着。

18 UI模块较多的项目,Activity应该按模块分包

19 函数的实现横不可超过半屏幕竖不可超过一屏 超过了就要按逻辑块抽出别的子函数。

20 用不到的第三方库就删掉

21 禁止使用静态变量在activity和activity之间、activity和service之间共享数据

22 Activity中在一个View.OnClickListener中处理所有的逻辑

23 不要重用父类的handler,对应一个类的handler也不应该让其子类用到,否则会导致message.what冲突

24 如果多个Activity中包含共同的UI处理,那么可以提炼一个父Activity,把通用部分封装起来由它来处理,其他activity只要继承它即可

25 屏幕适配:使用适配方案的值写死所有控件的尺寸

26 view与view之间不要直接通信 应该通过activity来转接

27 不要使用Log.i() Log.d() 进行日志打印,应该使用一个包含统一开关的测试类进行统一打印。比如封装一个LogUtils。

28 异常捕获不要直接catch(Exception ex),应该把异常细分处理

29 如果多段代码重复做同一件事情,说明此段代码各语句之间有实质性关联并且是完成同一件事,那么可以把此段代码构造成一个 新的函数。

30 不要使用难懂的技巧性很高的语句,除非很有必要时。

上一篇下一篇

猜你喜欢

热点阅读