Android开发规范

作者:陆金龙    发表时间:2018-04-06 14:55   

关键词:Android编程规范  

1 开发环境

1.1 IDE选择

1.1.1 Android Studio

Android studio与gradle的组合是目前android开发IDE的首选。

1.1.2 Eclipse

在Android Studio普及之前,Android项目大部分使用Eclipse开发。目前也有部分开源项目、第三方库及一些公司以前的项目是用Eclipse开发的,因此熟悉Eclipse进行Android开发也是必要的。

1.2 编程语言

1.2.1 Java

基于JVM设计的编程语言,之前的Android开发官方语言。

1.2.2 Kotlin

Google已宣布将Android开发的官方语言更换为Kotlin。

Kotlin的使用正在快速增长,一些大型互联网公司已经在使用。

Kotlin特性:类的属性、空指针安全、延迟初始化(lateinit)、Smart-Cast、类型推断、val定义常量、$符号格式化字符串、when取代了switch、循环中的区间概念、数据类、基类(Any)、单例类(object)、open修饰能继承的类、扩展方法、使用id访问XML中定义的View、Collection 的 Streams API、Lambda 、回调函数作为参数使用(类似C#的委托)等。

1.2.3 C/C++

应掌握基本的C/C++开发,以满足JNI开发的需要。

1.3 JDK和SDK版本

jdk和sdk版本都尽可能的跟随官方最新稳定版。

1.3.1 JDK

稳定版本jdk1.7.0_55、jdk1.8.0_92,新版本jdk-9.0.4、jdk-10,应该跟随官方适时更新版本,以便使用新增加的功能和语言特性。

1.3.2 SDK

Google新政策,在2018年8月以后发布的新应用,以及2018年11月以后更新的应用,必须以最新的 Android API 级别作为targetSdkVersion,目前为 26(Android 8.0)。

2 工程管理规范

2.1 工程项目配置

2.1.1签名信息的配置

在不会被添加到版本控制系统里的gradle.properties文件里,设置变量

KEYSTORE_PASSWORD=password123

KEY_PASSWORD=password789

在build.gradle中为发布编译定义 signingConfigs

signingConfigs {

  release {

  try{

    storeFile file("myapp.jks") 

    storePassword KEYSTORE_PASSWORD 

    keyAlias "thekey"

    keyPassword KEY_PASSWORD

 } catch(ex) {

   throw new InvalidUserDataException("You should define KEYSTORE_PASSWORD and KEY_PASSWORD in gradle.properties.") 

  }

}

}

2.2 工程目录结构

2.2.1 SDK目录

Android SDK放置在主目录里或其他与应用无关的地方。

2.2.2 app和module项目的内部目录

首先使用Gradle & Android Studio项目结构。

然后根据需要分别在res和java下规划资源目录和代码目录。

(1)资源目录

res下规划资源目录,需要考虑为不同屏幕密度(dpi)和不同屏幕宽度的设备提供适配,以及横竖屏的适配。

mipmap文件夹只放应用图标。其他需要使用的drawable资源放到对应的drawable文件夹。The mipmap folders are for placing your app icons in only. Any other drawable assets you use should be placed in the relevant drawable folders as before.

参考:https://www.jianshu.com/p/991c29a5e2b3

(2)Java目录

java代码目录结构可大致按如下方式规划,如果activity不多,则放在最高级的包里面,如果activity有多个,可以创建activitiy包:

2.2.3 多工程的目录位置

这里的目录是项目工程存放的物理目录,其结构主要体现在开发机机代码版本管理上,不体现在Android studio的视图界面。一级目录大体按以下几个部分划分,不同大类的库分别放到各自的一级目录下,便于管理:

Client 主应用

Modules 模块(功能模块)

Public 公共库(产品线)

SecPart 二方库(公司公共类库、中间件等)

ThirdPart 三方库(第三方类库)

2.2.4 基于框架的工程目录

 待续

2.3 软件发布

(1)签名发布

必须创建签名文件,为签名文件设置密钥。发布时使用该签名文件生成apk安装包。

(2)代码混淆

发布版本须进行混淆处理,即app下build.gradle文件的以下配置项minifyEnabled true

buildTypes {
    release {
        buildConfigField "boolean", "LOG_DEBUG", "false"
        //压缩混淆
        minifyEnabled true
        // 移除无用的resource文件
        shrinkResources true
        //前一部分代表系统默认的android程序的混淆文件,该文件已经包含了基本的混淆声明,后一个文件是自己的定义混淆文件
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
   }

对于涉及反射等原因不能混淆的代码,对相关类或接口(以及其成员)可在proguard-rules.pro文件中配置忽略项,防止被混淆。

(3)处理64Kbug问题

如果工程比较多,方法数超过65536,会导致编译和打包失败。解决办法如下:

在app下build.gradle文件的如下所示的defaultConfig 中添加项multiDexEnabled true,

在build.gradle文件的android里添加dexOptions项(防止编译的时候oom、GC)

在dependencies 添加compile 'com.android.support:multidex:1.0.1'

android {

 defaultConfig {

       applicationId "com.xxxx.client"

       minSdkVersion 21

        // others ......

       multiDexEnabled true

}

dexOptions {

javaMaxHeapSize "4g"

}

}

dependencies {

   compile 'com.android.support:multidex:1.0.1'

}

 

让应用的Application继承MultiDexApplication

public class MyApplication extends MultiDexApplication {//...}

AndroidManifest.xml中的application指定自定义的这个类

  <application android:name=".MyApplication"

.... />

3 命名规范

使用英文字母、下划线、数字等组合命名,文件夹有需要短横线的例外。

文件夹、包名、文件名、代码中类型和成员等所有类型的的命名,杜绝使用中文。

命名规范总体应多参考官方android源码,以及官方给出的规范建议。

3.1 版本命名规范

3.1.1 版本号说明

1.0.1.20180327_beta

版本号组成:主版本号.次版本号.修订版本号.日期版本(或编译版本号)_希腊版本号

其中希腊版本号有base、alpha、beta 、RC 、 release

Base:该软件通常包括所有的功能和页面布局,但功能都没有做完整的实现,只是做为软件的一个基础架构。

Alpha :内部版本,以实现软件功能为主,通常只在软件开发者内部交流。一般Bug较多,经开发人员修改Bug后,发布到测试网址让测试人员测试。

Beta :测试版本,相对于Alpha 版已经有了很大的进步,消除了严重错误,但还需要经过多次测试和修改,更多是软件的UI。修改了Bug 经测试人员测试确认关闭bug后可发布Beta 版到外网上。

RC :相当成熟了,基本上不存在导致错误的Bug,接近即将发行的正式版本。

Release:最终版本,最终交付用户使用的一个版本。该版本有时也称标准版。

3.1.2 版本号修改规则

(1)主版本号:整体架构发生变化或不兼容的API变更时增加。次版本号和修订版本号归零。

(2)次版本号:新增了功能模块,或是功能模块有大的或不兼容的改动。修订版本号归零。

(3)修订版本号:bug修复、小的变动、功能的扩展。由项目经理决定是否修改。

(4)日期/编译版本号:记录项目的当前日期或者记录随当天编译次数递增的数字,由开发人员决定修改。

大部分发布出去的版本号使用前3段,首发版本一般使用1.0.0。

3.2 代码命名规范

3.2.1 包名

域后缀倒置的加上自定义的包名,采用小写字母,格式如下:com.companyname.modulename

3.2.2 类名和接口名

Pascal命名法,使用完整英文单词组合描述。

Android中的几种接口命名(参考Java和Android源码):

IBinder 功能接口

Cloneable、Serializable、Parcelable  功能接口

OnClickListener、OnKeyListener 监听接口

ComponentCallbacks、LoaderManager.LoaderCallbacks 回调接口

3.2.3 方法名

camel(驼峰)命名法,使用命名法英文单词组合。

使用动宾结构,动词说明需要做的操作,宾语表示作用的对象,如getUser()

方法名过长的,可以对部分单词使用较通用的缩写,如Infomation缩写为Info,Manager缩写为Mgr,Administrator缩写为Admin等,但是不要滥用缩写,以保障可读性为前提。

3.2.4 属性名

camel(驼峰)命名法,使用命名法英文单词组合。

属性名不能与方法名相同。

属性名不能和局部变量相同。

属性名不可以和公有方法参数相同,如果相同,需要使用this来表示成员变量。

引用静态成员变量时使用类名引用,即使是在类内部使用。

 

Google官方有一种做法,android源码中有很多类的实例属性是用m做前缀的,静态属性用s作前缀。

建议在编写框架性质的类时可参照该种命名方式,在编写业务类时可不作强制要求只要遵循驼峰命名法即可。(带前缀的命名相对麻烦一点,但可读性好,在代码量小及不经常变化的类中可以考虑采用)

Non-public, non-static field names start with m.

Static field names start with s.

Other fields start with a lower case letter.

Public static final fields (constants) are ALL_CAPS_WITH_UNDERSCORES.

3.2.5 常量名

全大写的英文描述,英文单词之间用下划线分隔开,并且使用final static 修饰。 

3.2.6 资源名

1. 资源文件命名

状态选择器:

sl_button.xml

sl_list_item.xml

背景、边框:

bg_primary.xml (无圆角)背景

bg_primary_sm.xml 小圆角背景

bg_primary_md.xml  中圆角背景

border_primary.xml 无圆角边框

border_primary_sm.xml 小圆角边框

border_primary_md.xml中圆角边框

动画:

fade_in.xml 淡入

fade_out.xml 淡出

push_down_in.xml 从下方推入

push_down_out.xml 从下方推出

push_left.xml 推向左方

slide_in_from_top.xml 从头部滑动进入

zoom_enter.xml 变形进入

slide_in.xml 滑动进入

shrink_to_middle.xml 中间缩小

菜单:

menu_main.xml

字符串:

strings.xml 、strings_contact.xml (字符串资源较多时,可分类放到不同的文件里)

颜色:

colors.xml、colors_chat.xml、

2. 布局文件命名

遵循加前缀的惯例,非app模块的layout命名再加上模块前缀,例如:

activity_main.xml

modulename_activity_main.xml(非app模块的layout)

fragment_user_info.xml

view_toolbar.xml

view_top_slide_tab.xml

view_bottom_tab.xml

widget_draw_board.xml  (自定义组件的布局资源文件)

list_item_user.xml

list_header.xml

list_footer.xml

grid_item_user.xml  

3. 布局文件中资源名

资源id命名规则:

在语义名前加上前缀(View类别的缩写),如下所示的tv_desc、btn_bind等。(如果使用kotlin的扩展库,在代码中直接通过id访问资源对象,也可按驼峰命名法格式组织命名,如tvDesc、btnBind、btnUnbind)

各视图控件的缩写前缀:

RelativeLayout rl

LinearLayout ll

FrameLayout fl

TableLayout tl

WebView webv

ScrollView scrollv

ListView lv

GridView gv

ViewPager vpager

 

TextView tv

EditText et

ImageView iv

Button btn

ImageButton ibtn

CheckBox ckb

RadioButton rdb

DatePicker dpk

TimePicker tpk

ProgressBar prgbar

icon ic

divider di

4.布局文件组织建议:

结束标志位 />独占一行,或者前面留出空格,便于对属性排序或添加

android:id永远放在第一个;

android:layout_** 布局属性要紧接着id靠近顶部;

android:textColor="" 之后才是样式

android:text="绑定" 最后是控件的值

<TextView android:id="@+id/tv_desc"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_gravity="center_horizontal"
      android:textAlignment="center"
      android:textColor="@android:color/darker_gray"
      android:text="服务绑定与解绑定的测试" />

4 编码规范

4.1 Java编码规范

参考Google Java编程风格指南、阿里巴巴Java开发手册

4.2 Android编码规范

配置相关

要使用用ProGuard 或 DexGuard

避免引用大容量的第三方库,导致客户端包非常大

使用框架

1)不要自己实现Http客户端,使用Volley、OkHttp或Retrofit库;

2)不要自己解析JSON数据,使用Jackson或Gson来解析JSON数据;

3)使用Glide、ImageLoader等第三方组件处理图片加载;

4)使用GreenDao等处理数据库操作;

5)使用权限框架Permissions4M统一处理权限请求;

6)使用blockcanary监控UI卡顿;

7)使用Leakcanary检测内存泄漏,并进行修复;

8)使用AOP处理一些通用逻辑,如针对所有Activity界面的网络中断通知,如ARouter路由跳转,或者OkDeepLink(兼容RxJava);

分工合作

1)提炼一个BaseActivity,把处理通用逻辑,其他activity只要继承它

2)使用Fragment来绘制UI界面,Activity主要用来管理Fragment

3)activity中在一个View.OnClickListener中处理所有的逻辑

4)处理应用全局异常和错误,将错误以邮件的形式发送给服务端
Log(接口名称或类名,详细描述)

资源管理

为避免冲突,将通用组件drawable/layout/values目录下的文件名增加前缀

使用styles以避免重复的属性,使用多个style文件分类管理

使用strings文件管理字符串资源,使用多个string文件分类管理

使用dimens文件管理尺寸值,短小而DRY,定义通用常量

使用colors.xml文件管理颜色值,短小而DRY,定义常用颜色

使用layer-list和selector,定义不同状态的资源
strings.xml中使用%1$s实现字符串的通配

 

参考资源:

浅谈Android开发中项目的文件结构及规范化部署建议 by iam_wingjay

android命名规范 by 萧影随行558