美文网首页
Android 编码规范

Android 编码规范

作者: 古早味蛋糕 | 来源:发表于2022-11-23 19:03 被阅读0次

    1 命名规范

    1.1 Android包命名规范

    因为Android包目录的命名会直接影响到整个App工程后期的开发效率和扩展性,所以在创建项目的初期,包目录的命名非常重要。
    Android工程本身对包目录命名没有要求,可以将代码文件直接放置在默认目录下,但这样做会导致很多无关文件的堆积,不利于查找及后期维护,所以一般不建议采用这种方式。Android包目录命名的常用方式有两种:PBL(Package By Layer)和PBF(Package By Feature)。

    1. Package By Layer

    PBL是按层次划分的,实际上就是按照职能划分,如在根目录里面命名activity、fragment、view、service、db、net、util、bean、base等包名。
    例如,activity的职能是管理所有的Activity类,只要这个类是继承自Activity的,都放到这个目录下。以此类推,fragment目录存放所有继承自Fragment的类,view放置自定义的View,net放置网络相关的类,bean放置Bean对象等。
    早期的Android App开发常采用图1.1所示的包结构。
    接下来我们来分析一下PBL这种命名结构的优缺点。
    1)PBL优点

    • 项目结构简洁明了,上手快。
    • 适合开发人员不多、项目功能简单、后期变动不大的项目。

    2)PBL缺点
    (1)低内聚
    同一个目录下会有各种功能模块。例如activity目录,其中放置了登录、设置等功能模块;这几个模块本身并没有很强的关联性,却被放置在了一起,导致聚合性降低。(2)高耦合
    这里讲的高耦合是指目录之间的关联性,例如activity目录内的类可能引用到了fragment或者view目录里面的类,导致目录之间的耦合性较高。
    (3)影响开发效率
    开发一个功能模块,往往需要在不同的包目录之间切换。例如登录模块,需要在activity目录下开发LoginActivity类,而LoginActivity类往往包含了fragment目录下的内容,这时又需要去fragment目录下找到对应的Fragment类来开发,目录之间频繁切换会影响开发效率。同样,修改、调试一个功能也需要进行这样的操作,如果后期项目功能和代码增多,会大大降低开发效率。

    1.1PBL包目录结构.png
    2. Package By Feature

    PBF是按照功能划分包目录的。以功能模块名称作为目录名,所有与这个功能模块相关的开发都在这个目录内。以Google I/O 2019 Android App为例,如图1.2所示。


    图1.2GoogleApp包目录结构.png

    可以看到,除了与业务无关的模块,如utils这样的通用模块,每一个包目录都对应一个功能模块。
    Google的项目采用PBF进行包目录命名,我们来分析一下PBF有哪些优点。
    1)高内聚
    所有功能都在一个包下完成,以map模块为例,如图1.3所示。可以看到,map目录下包含了fragment、adapter、viewmodel等。这里需要说明的是,功能模块里面的util一般都是和这个功能模块强相关的,如果是功能模块包目录外的util目录名,一般放置的是与项目相关的util类和能作用于整个或者多个功能模块的util类。其他包目录以此类推,例如ui包目录下面放置了Base Activity,adapter包目录下面放置了BaseAdapter等。

    图1.3map模块包目录结构.png

    2)低耦合
    包目录之间没有很强的关联性,此模块的功能只需要在对应的包目录下面即可进行开发,除了基础类外,一般不需要引入其他包的类。
    3)开发效率高
    增删改查都只需要在对应的包目录下面操作即可,便于团队开发管理,提升问题排查效率,也方便后续开发人员接手。
    4)便于后期组件化转化
    如果项目是按照PBF来进行包目录划分的,后期进行组件化改造的时候就会非常方便。可以直接把功能模块独立出来作为一个组件,同时划分好代码边界,对外保留好模块间的访问接口。例如上面的map功能模块,可以将其独立出来作为一个library工程。

    1.2 Android代码命名规范

    以Java语言为例,来说明一下如何制定代码的命名规范。命名规则约定事项如下。

    • 代码命名不以下画线和美元符号开头。
    • 【】表示可选。
    1. 类名采用大驼峰命名法。

    (1)命名规则【功能】 + 【类型】。
    (2)举例Activity类,命名以Activity为后缀,如:LoginActivity。
    Fragment类,命名以Fragment为后缀,如:ShareFragment。
    Service类,命名以Service为后缀,如:DownloadService。
    Dialog类,命名以Dialog为后缀,如:ShareDialog。
    Adapter类,命名以Adapter为后缀,如:ProductAdapter。
    BroadcastReceiver类,命名以Receiver为后缀,如:PushReceiver。
    ContentProvider类,命名以Provider为后缀,如:FileProvider。
    业务处理类,命名以Manager为后缀,如:UserManager。
    解析类,命名以Parser为后缀,如:NewsParser。
    工具类,命名以Util为后缀,如:EncryptUtil。
    模型类,命名以Bean为后缀,如:GiftBean。
    接口实现类,命名以Impl为后缀,如:DeviceImpl。
    自定义共享基础类,命名以Base开头,如:BaseActivity。
    测试类,命名以它要测试的类的名称开始,以Test结束,如:DeviceImplTest。
    (3)抽象类和接口类
    抽象类命名后缀为Abstract,如:abstract DeviceAbstract。
    接口类命名后缀为Contract,如:interface DeviceContract。

    2. 方法名采用小驼峰命名法。

    (1)命名规则动词或动名词。如:run()、addDevice()。
    (2)举例初始化方法,命名以init开头,如:initView。
    按钮点击方法,命名以to开头,如:toLogin。
    设置方法,命名以set开头,如:setData。
    具有返回值的获取方法,命名以get开头,如:getData。
    通过异步加载数据的方法,命名以load开头,如:loadData。
    布尔型的判断方法,命名以is、has或check开头,如:isEmpty、checkNull。
    对数据进行处理,命名以handle开头,如:handleUserInfo。
    弹出提示框,命名以show开头,如:showAgreement。
    更新数据,命名以update开头,如:updateUserInfo。
    保存数据,命名以save开头,如:saveUserInfo。
    重置数据,命名以reset开头,如:resetUserInfo。
    删除数据,命名以delete开头,如:deleteUserInfo。
    查询数据,命名以query开头,如:queryUserInfo。
    移除数据,命名以remove开头,如:removeUserInfo。

    3. 变量名

    采用小驼峰命名法,变量命名应该简短且有规则。
    所有变量都要显示地赋值,如int number =0。
    布尔变量应该包含Is,如IsFirstLogin。
    按照不同的变量类型,变量的命名规则有所不同,如下。
    (1)类变量(成员变量)非公有的变量前面要加上小写m;
    静态变量前面要加上小写s;
    其他变量以小写字母开头,前面不再加任何前缀,例如Bean类中的属性变量,为了生成的get和set方法名美观可读,有一些IDE已经支持生成get和set方法名时自动去除前缀。
    常量、静态变量全大写,采用下画线命名法。

    public class Demo {
      public static final int SOME_CONSTANT = 2022;
      public int publicField = 1;
      private static Demo sSingleton;
      int mPackagePrivate;
      private int mPrivate = 0;
      protected int mProtected = 10;
    }
    

    (2)局部变量变量为一个单词,以小写字母开头。如:GiftBean bean。
    (3)参数参数为一个或多个单词的组合,以小写字母开头。如:fun(int position)、fun(String userName)。
    (4)临时变量临时变量通常被取名为i、j、k、m和n,它们一般用于整型;c、d、e一般用于字符型。如:for (int i = 0; i < len ; i++),for (String c : stringList)。
    (5)泛型变量泛型变量一般用单个大写字母来表示,如果这个泛型是某个类的子类,那么这个大写字母一般取的是父类所代表的这个类含义的首字母。如:interface BasePresenter<V extends BaseView,M extends BaseModel> ,其中V代表View,M代表Model。
    (6)控件变量Android中把很多UI控件作为成员变量,为了和Java的成员变量区分开,UI控件类型的成员变量在遵循前面成员变量命名规范的前提下,后面统一再加上控件名称。如:private TextView mDescriptionTextView。
    有些命名规则是在后面加上控件的缩写,缩写不如全名看起来美观,而且不易于理解

    1.3 Android资源文件命名规范

    1. layout命名

    全部小写,采用下画线命名法,使用名词或名词词组。所有Activity或Fragment等的布局名必须与其类名相对应。
    (1)命名规则【类型名】+【模块名】。
    (2)举例
    MainActivity.java对应activity_main.xml,规则是类名单词倒置,中间用“”连接,并且单词全部改为小写,如下。
    activity_main:Main模块的Activity。
    fragment_login:Login模块的Fragment。
    dialog_update:Update模块的Dialog。
    关于include,由于include的布局一般不属于某个专门的模块,所以用include
    代表类型。
    如果是在某个模块内拆分出来的布局,需要加上这个模块的名称,如下。
    include_tips:提供tips布局。
    include_im_function:IM模块的功能布局。
    关于ListView、RecyclerView或GridView的item的布局命名,用item_代表类型,如下。
    item_user_member:User模块下普通会员的item。
    item_user_vip:User模块下VIP会员的item。
    另外,item如果是表示header或footer的,可以加上_header或_footer后缀,如下。
    item_user_header:User模块下下拉刷新的header。
    item_user_footer:User模块下下拉刷新的footer。
    总之,布局文件的命名需要能直接反映该布局文件的作用范围和功能。

    2. layout中的id命名全部小写,采用下画线命名法。

    (1)命名规则【控件缩写】+【模块名】+【功能名】。
    (2)举例

    <!-- 这是登录模块的密码输入框 -->
    <TextView
     android:id="@+id/et_login_password"
         />
        
    <!-- 这是登录按钮 -->
    <Button
     android:id="@+id/btn_login_submit"
         />
    

    有时候为了简洁,layout的id定义得不那么复杂,例如上面的et_login_password可能会写成password。这样有一个问题是,如果项目中存在多个相同的命名,那么查找起来会有些不方便,如图1.4所示的同名id


    图1.4同名id.png

    在单击main_content这个id名后,系统会弹出对话框提示选择跳转到哪一个layout下面的id。这样会增加开发时间,尤其是在对代码的熟悉程度不够的情况下。而且如果是在SDK中这样去命名,很有可能会导致引用SDK的项目出现资源重名并产生冲突。

    1. anim
      命名全部小写,采用下画线命名法。
      (1)命名规则【模块名】+【动画类型】+【动画方向】。如果不限定模块名,表示这个动画是全局通用的。
      (2)举例scale_in.xml:缩小;slide_out.xml:扩大。fade_in.xml:淡入;fade_out.xml:淡出。push_down_in.xml:从下方推入;push_down_out.xml:从下方推出。left_in.xml:从左边进入;left_out.xml:从左边退出。welcome_zoom_in.xml:欢迎界面放大。

    2. mipmap(或drawable)
      命名全部小写,采用下画线命名法。
      (1)命名规则【控件缩写】+【模块名】+【功能名】+【状态限定】。状态限定的内容包括small、big、normal、focus、red、white等,且可以叠加。
      (2)举例btn_main_back.png:Main模块的返回按钮的图片。
      btn_main_back_small.png:Main模块的返回按钮的小图片。
      btn_main_back_small_pressed.png:Main模块的返回按钮被选中时的小图片。
      btn_red.png:通用红色按钮图片。
      bg_setting.png:Setting模块通用背景图片。ic_user_head_small.png:User模块头像(小)。selector_login_input.png:Login模块输入文本框的selector。

    3. values中的id命名
      1)strings
      (1)命名规则【模块名】+【控件名】+【功能名】。
      (2)举例

      <string name="loading">加载中</string>
      <string name="button_ok">确定</string>
      <string name="dialog_title">对话框</string>
      <string name="main_titlebar_more">更多</string>
      <string name="setting_title">设置页面</string>
      <string name="search_edittext_hint">输入关键字</string>
      <string name="login_findpassword">找回密码</string>
      

    2)colors
    (1)命名规则【模块名或theme名】+【功能名】+【颜色编码】。
    (2)举例

       <!-- Basic colors -->
       <color name="white">#FFFFFF</color>
       <color name="black">#000000</color>
       <color name="red">#FF0000</color>
       <color name="blue">#0000FF</color>
       <color name="green">#00FF00</color>
       <!-- Splash page -->
       <color name="splash_yellow">#EEEE00</color>
       <color name="splash_pink">#FFB5C5</color>
       <!-- Feedback page -->
       <color name="feedback_submit_black">#000000</color>
    

    3)dimens
    (1)命名规则【模块名】+【控件名】+【描述】。
    (2)举例

       <!-- Common dimensions -->
       <dimen name="margin_normal">16dp</dimen>
       <dimen name="margin_small">8dp</dimen>
       <dimen name="margin_large">32dp</dimen>
       <!-- Navigation -->
       <dimen name="nav_drawer_width">@dimen/match_parent</dimen>
       <dimen name="nav_account_image_size">32dp</dimen>
       <dimen name="nav_header_logo_size">36dp</dimen>
    

    4)styles采用大驼峰命名法。
    (1)命名规则【模块名.】+【功能名】。
    (2)举例

       <style name="ContentStyle">
          <item name="android:layout_weight">1</item>
          <item name="android:layout_width">0dp</item>
       </style>
       <style name="Login.ContentStyle">
          <item name="android:layout_weight">1</item>
          <item name="android:layout_width">0dp</item>
          <item name="android:textSize">14sp</item>
          <item name="android:gravity">center</item>
       </style>
    

    Android大部分编码就这些了,其他的规范可以依上面的思路进行设计。

    相关文章

      网友评论

          本文标题:Android 编码规范

          本文链接:https://www.haomeiwen.com/subject/kxhaxdtx.html