1.2 代码规范

1.2.1 IDE规范

Android开发的IDE有很多种,Eclipse就是曾经的“霸主”,但是在2015年6月,Google官方宣布Android Studio作为Android开发的IDE,之后Eclipse就逐渐淡出了。目前Android开发的IDE主要是Android Studio,但是也有其他的一些IDE可以用来开发Android,如IntelliJ IDEA。

还有就是如果涉及混合开发,那么可选的IDE就更多了,例如可以使用VSCode进行Flutter的开发。

Android Studio实际上也是源自IntelliJ IDEA的,只是在IntelliJ IDEA社区版上剔除了其他功能,只留下专用于Android开发的插件。

这里以Android Studio为例,先介绍下基本的配置规范。

·保持IDE版本最新,保持开发人员的IDE版本一致。

·IDE统一编码格式为UTF-8,如图1.5所示。

·编码完成后记得按Ctrl + Alt + L快捷键格式化代码。

·安装一些常用的Android Studio插件,如GsonFormat等。

图1.5 IDE设置编码格式

1.2.2 CheckStyle

在开发App的过程中,每个团队都会制定自己的代码规范,也可以叫作代码格式。但是在实际开发过程中我们发现,要么由于开发周期短,开发人员常常没有按照规范进行开发,而是按照自己的编程习惯来开发,要么是新入职的员工,或者从其他项目组借调过来的开发人员,不熟悉当前项目的开发规范,引入了自己常用的代码开发格式。因此有必要采用一些强制手段来执行我们设定的代码规范。

这里引入CheckStyle来执行代码规范。

CheckStyle有两种使用方式,一种是安装插件,还有一种是通过gradle配置。

1. 安装CheckStyle插件

1)安装插件

在Plugins里面搜索CheckStyle-IDEA,如图1.6所示。

图1.6 搜索CheckStyle-IDEA插件

安装完成后选择Google Checks,作为项目默认的配置文件,如图1.7所示。

图1.7 选择Google Checks

以整个项目为范围,运行CheckStyle,结果如图1.8所示。

图1.8 CheckStyle运行结果

2)CheckStyle文件

关于CheckStyle的详细介绍,可以访问CheckStyle官网。

Android Studio默认提供了Google和Sun的CheckStyle文件,我们可以在设置中找到它们。可以选择其中的一个作为自己项目的CheckStyle。

3)实例

打开一个Java文件,右键单击以运行Check Current File,结果如图1.9所示。

图1.9 运行Check Current File

根据提示进行部分修改后,结果如图1.10所示。

图1.10 修改后运行结果

4)自定义CheckStyle

每个公司,甚至每个团队都应该有自己的CheckStyle文件。可参考Google或其他公司的CheckStyle文件,自行修改成为适合自己团队使用的代码规范文件。

随书源码中有一个自定义的CheckStyle文件供读者查阅。

2. 通过gradle执行CheckStyle

有两种方式可以通过配置gradle脚本使用CheckStyle,如下。

·可以直接运行命令执行CheckStyle;

·可以在运行Build任务的时候,同时触发CheckStyle任务,用来检测代码规范性。如果不符合代码规范,停止运行,并且提供HTML文件查看错误详情,直到代码完全符合我们定义的代码规范才能继续运行。

建议使用第二种方式,通过强制性的脚本检测以保证每个团队成员提交的代码都是符合代码规范的。接下来介绍这种方式是如何实现的。

首先,新建一个checkstyle.gradle文件,内容如下。


1. allprojects {
2. project ->
3. // 代码规范检查
4. apply plugin: 'checkstyle'
5. checkstyle {
6. configFile rootProject.file('config/quality/checkstyle/checkstyle.xml') 7. toolVersion '8.18'
8. ignoreFailures false
9. showViolations true
10. }
11. task('checkstyle', type: Checkstyle){ 12. source 'src/main/j ava'
13. include '**/*.j ava'
14. exclude '**/gen/**'
15. classpath = files()
16. }
17. tasks.whenTaskAdded { task ->
18. boolean runCheckStyleOnLocalDev = "${enable_checkstyle}"
19. .toBoolean() 
20. boolean runCheckStyleTask = task.name == 'prepareReleaseDependencies' ||
(runCheckStyleOnLocalDev && task.name == 'preBuild')
21. if (runCheckStyleTask){ //prepareReleaseDependencies, preBuild
22. println("checkstyle run task.name :" + task.name)
23. task.dependsOn 'checkstyle'
24. }
25. }
26. }

其中config/quality/checkstyle/checkstyle.xml是项目中CheckStyle文件的路径。

然后在项目的build.gradle文件中加上如下代码。


1. apply from: './checkstyle.gradle'

第一种方式是直接运行CheckStyle的Gradle脚本,在terminal里面输入“gradlew checkstyle”,即可运行CheckStyle任务。

第二种方式是在运行Build任务的时候自动检测CheckStyle。按Ctrl+B快捷键运行Build任务,同时触发 checkstyle.gradle文件中的任务。

如果有错误,日志中会提供一个查看报告结果的路径,可以打开这个HTML文件格式的报表,查看详细的检查结果,然后对比将代码修改成符合我们定义的代码规范的代码。

需要注意的是,如果错误太多,输出的消息中不一定会包含检查结果路径。如果没输出,可以到各个工程module的build\reports\checkstyle路径下进行查看。

图1.11所示为CheckStyle检测结果报表的内容。

图1.11 CheckStyle检测结果报表

单击链接可以看到详细的描述,如图1.12所示。

图1.12 详细的描述

3. CheckStyle的155条规范

CheckStyle官网提供了检查标准,截至目前一共有155条规范。在编写CheckStyle的时候可以按照这些规范来编写,单击链接可查看详细的属性介绍。

图1.13所示为FileLength规范。

图1.13 FileLength规范

4. 格式化代码

在编码完成后,我们要养成将文件格式化的习惯,保证文件符合我们CheckStyle定义的代码规范。

选择CheckStyle文件,如图1.14所示。

图1.14 选择CheckStyle文件

然后在代码文件中按Ctrl + Alt + L快捷键即可将代码按照我们定义的代码规范格式化。

这里需要注意的是,并不是所有定义的代码规范都能够通过按Ctrl + Alt + L快捷键来得以实施,例如定义了每一行的字符长度不能超过140个字符,若某行的字符长度超过140个字符,那么格式化也不能将该行自动换行。

1.2.3 代码注释

为了方便自己和他人阅读代码,请做好注释。代码不仅是用来运行的,还是用来给人阅读的。

如果没有注释,那么会给代码阅读以及问题排查带来不便,例如其他开发人员接手某块代码的开发工作时,如果有详细的注释,那么接手的开发人员能很快地了解这块代码的业务逻辑以及解决思路。同样,项目的一部分功能也会经常交给新员工来解决,新员工往往需要花费大量时间阅读代码,如果有详细的注释,新员工阅读和理解代码的效率就会提升;否则新员工有可能会经常请教老员工,在一定程度上占用老员工的开发时间,影响彼此的工作效率。

所以说代码注释也是需要特别关注的一项内容。

1. 文件头注释

在文件头注释中添加版权声明。

1)示例


1. /**
2. * Copyright (c) 2020 Your Company. All rights reserved.
3. */

2)设置

在Android Studio中依次单击File → Settings → Editor → File and Code Templates →Includes → File Header,如图1.15所示,设置File Header的内容。

图1.15 设置File Header的内容

还可以创建注释模板文件,如图1.16所示的Company Declare文件。

图1.16 创建Company Declare文件

在Class中添加这个文件,如图1.17所示。

图1.17 添加Company Declare文件

在新建Java文件的时候,这个文件头注释也会自动生成,如图1.18所示。

图1.18 带有文件头注释的新建Java文件

2. 类注释

1)示例


1. /**
2. * 对类的描述3. * @author: 张三
4. * @e-mail: xxx@xx
5. * @time: ${date}${time} 6. * @version: 1.0
7. */

2)设置

在File Header中添加即可。

3. 方法头注释

每一个成员方法(包括自定义成员方法、覆盖方法、属性方法)的方法头都必须做方法头注释。

在方法前一行输入/**并按Enter键,或者在Android Studio中设置Fix doc comment(Settings → Keymap → Fix doc comment)快捷键,Android Studio会自动生成注释模板,我们只需要补全参数即可。


1. /**
2. * 对方法的说明
3. * @param id 查询用ID
4. * @return User实体类
5. */

4. 通用注释

对于注释,还可以设定通用注释模板,然后通过快捷输入的方式让IDE自动生成设定的注释内容。这样可以在代码的任何地方快捷生成注释,提升编码效率。如图1.19所示。

图1.19 创建通用注释模板

在Android Studio中依次单击File → Settings → Editor → Live Templates,新建一个名为MyComment的Group,然后新建一个名为cmt的缩写,再输入通用注释模板内容。这样在代码里面输入cmt然后按Enter键,就会自动生成通用注释模板内容。

5. 方法体内代码的注释

1)对代码块注释


1. /***************** 说明 ******************/

2)对单行注释


1. // 说明

3)对多行注释


1. /*
2. * 说明1
3. * 说明2
4. */

6. 常量和变量的注释

下面几种情况下的常量和变量,都需要添加注释,优先采用在代码右侧添加//符号的方法来注释,若注释太长则在代码上方添加注释。

·接口中定义的所有常量。

·公有类的公有常量。

·枚举类定义的所有枚举常量。

·实体类的所有属性变量。


1. public static final int TYPE_DOG = 1; // 狗2. public static final int TYPE_CAT = 2; // 猫
3. public static final int TYPE_PIG = 3; // 猪4.
5. private int id; // id
6. private String name; // 名称
7. private String sex; // 性别

7. 资源文件注释

在1.1.3小节介绍的资源文件中,如果需要添加注释,使用如下格式。


1. <!-- Toast信息 -->

8. TODO、FIXME注释

TODO代表需要实现,但目前还未实现的功能说明。FIXME代表功能代码有问题,需要修复的说明。

在Android Studio左下角的TODO里面可以看到当前项目所有的TODO和FIXME注释,如图1.20所示。

图1.20 TODO和FIXME注释

1.2.4 JavaDoc

在介绍了代码注释规范后,在开发过程中我们会在文件中按规范添加代码注释。

如果打算更进一步地将整个项目的代码注释规范地整理出来,形成一份文档交给用户,应该怎么办呢?这里我们引入JavaDoc。

JavaDoc是Sun公司提供的一种技术,即从程序源代码中抽取类、方法、成员等注释,形成一个和源代码配套的API帮助文档。

1. JavaDoc标签

JavaDoc标签有很多,符合JavaDoc标签规范的注释能够在生成的文档中显示出来。此处以@param为例,介绍JavaDoc标签的用法。

@param的用法是在其后接参数名和描述。


1. /**
2. * startActivityForResult
3. *
4. * @param clazz 类名.class,获取类型类
5. * @param requestCode 请求码
6. */
7. protected void readyGoForResult(Class<?> clazz, int requestCode) { 8. Intent intent = getGoIntent(clazz);
9. startActivityForResult(intent, requestCode);
10. }

在生成的JavaDoc中的效果如图1.21所示。

图1.21 JavaDoc中的效果

2. 通过Android Studio导出JavaDoc

图1.22展示了如何配置JavaDoc。在Android Studio中依次单击File → Settings → Editor →Code Style → Java → JavaDoc。

图1.22 JavaDoc配置

JavaDoc的输出也很简单,在Android Studio中通过单击Tools → Generate JavaDoc……即可导出JavaDoc文档。

导出JavaDoc文档的时候有些常见的问题需要注意,例如提示:编码GBK的不可映射字符。

这是在utf-8项目中经常会遇到的问题,其实也就是字符编码问题。可以在VM的setting中进行图1.23所示的设置。

图1.23 JavaDoc设置

3. 通过gradle导出javadoc

除了上述导出JavaDoc的方法,还可以通过Gradle脚本配置来自动生成javadoc文件。在module的build.gradle中进行配置:


1. task j avadoc(type: Javadoc) {
2. source = android.sourceSets.main.j ava.srcDirs
3. classpath += project.files(android.getBootClasspath().j oin(File.pathSeparator)) 4. }
5.
6. task j avadocJar(type: Jar, dependsOn: j avadoc) {
7. classifier = 'j avadoc'
8. from j avadoc.destinationDir
9. }
10.
11. artifacts {
12. archives j avadocJar
13. }

接下来在Android Studio右侧的gradle这个tab里,找到这个module中的javadocJar脚本,双击运行,在该module的build目录下会自动创建javadoc文件,如图1.24所示。

图1.24 生成的javadoc文件

1.2.5 .gitignore

.gitignore的作用是忽略指定文件的上传,否则在提交代码的时候,项目中的所有文件都会提示可以上传,但是有一些文件(如本地编译文件)实际上不需要上传到服务器中;还有一些文件里面有用户的账号密码,涉及安全信息,也不应该上传。因此我们通过配置.gitignore文件,来决定哪些可以上传,哪些不用上传。

Github上有一个gitignore项目,专门提供了一系列的针对不同语言的gitignore模板。

编写.gitignore文件需要注意以下几点。

·#表示此行不生效,一般用来写注释。

·*表示通配符,如*.dex表示所有的dex文件。

·目录路径以 / 结尾,如build/表示所有build目录下的文件。

·特定文件直接写明文件名,如freeline.py。

随书源码中我们也提供了一个Android通用的.gitignore模板以供参考,实际开发过程中可以根据项目的情况进行修改。

1.2.6 ProGuard

1. ProGuard简介

Java源码编译后成为字节码,保存在class文件中,而出于跨平台考虑,class文件会保存类名、方法名、属性名等信息。而这些信息是很容易被反编译成Java源码的。

ProGuard是一种字节码优化工具,通过它可以删除无用的代码,并且将代码中的类名、方法名、属性名替换成简短并难以理解的名称,从而达到代码压缩、混淆、优化的目的。经过ProGuard混淆后的App往往体积会缩小(一般可以缩小25%左右),并且经过混淆后会给反编译增大难度,在一定程度上防止了App的逆向。

2. ProGuard语法

先介绍下Android Studio中ProGuard的配置。

·minifyEnabled:混淆开关。

·proguard-android.txt:SDK中ProGuard的默认配置规则。

·proguard-rules.pro:自定义ProGuard的配置规则。

编写的ProGuard内容不仅可以存在于proguard-rules.pro文件中,还可以自定义一个.pro文件(如my-proguard.pro),然后在proguard-rules.pro中通过–include引入:


1. -include my-proguard.pro

另外需要注意的是,并不是所有文件都能被混淆,以下几种类型的类不能使用混淆。

·反射用到的类。

·Jni中调用的类。

·AndroidManifest中配置的类,如Activity、Fragment及Framework中的类。

·其他情况会受到混淆影响的类。例如定义一个TAG常量,我们可能会通过这种方式来获取类名:Demo.class.getSimpleName(); TAG提供给输出日志使用,混淆后,日志中看不到原本的类名,所以此处的TAG一般直接使用常量“Demo”。

随书源码中有ProGuard的详细语法介绍。

3. ProGuard模板

如果ProGuard配置得不好的话可能会带来难以预料的问题,常见的如导致App崩溃等,而且增大了Bug的排查难度。

例如测试环境一般不使用ProGuard,但是在正式环境中会启用ProGuard,就会出现测试环境运行正常,但是正式环境异常甚至崩溃的情况。这种情况可以从ProGuard启用混淆的角度来进行排查。

因此整理一份混淆配置模板是一项必要的工作,随书源码中整理了一套Android ProGuard模板,这是在实际开发过程中总结出来的,可以直接参考使用,非常方便。