近日在搜MVP模式作为安卓项目架构时候,发现GitHub上一篇介绍MVP架构的文章。一看star已经超过2K了。作者同项目的这篇文章讲安卓项目和代码风格指南,也非常有参考价值。为了方便大家查阅,把原文翻译了一下。点击查看作者介绍安卓MVP架构指南的翻译文章。
新项目应该遵循安卓Gradle项目结构,定义在这里 :
安卓Gradle插件用户指南
。
项目ribot Boilerplate
是一个很好的参考。
1.2.1 类文件
类名书写方式是 大写的驼峰命名.
继承于安卓组件的类,名称应该以继承的组件命名,比如:SignInActivity, SignInFragment, ImageUploaderService, ChangePasswordDialog.
1.2.2 资源文件
资源文件书写方式:小写_下划线。如:ic_launcher.png
1.2.2.1 Drawable 文件
drawable类型资源命名:
图标(icons)命名方式 (取自 安卓图标官方指南):
selector 状态命名方式:
1.2.2.2 布局文件
布局文件应该跟对应的安卓组件名称匹配,但是把最顶级的组件名称放在前面。比如,当我们创建一个用于 SignInActivity的布局,那布局文件名称应该是activity_sign_in.xml.
一个稍微不同的地方是当我们创建用于Adapter渲染的布局,如填充一个 ListView, 在这种情况下,布局文件命名应该是用 item
开始。
注意有些地方这些规则没法应用,如,当我们创建一个布局文件,用于渲染另一个布局的一部分,这样的情况下,我们应该使用partial
前缀。
1.2.2.3 菜单文件
跟布局文件相似,按钮文件应该跟对应的组件匹配。比如:当我们定义一个菜单,用于 UserActivity,那么文件名应该是 activity_user.xml
文件名不含有menu是个良好的习惯做法,因为这些文件已经位于 menu 目录了。
1.2.2.4 取值文件(Values files)
在values文件夹的资源文件应该是复数形式(plural),比如,strings.xml, styles.xml, colors.xml, dimens.xml, attrs.xml
2.1.1 不要忽略了异常
你万不该这样做:
void setServerPort(String value) {
try {
serverPort = Integer.parseInt(value);
} catch (NumberFormatException e) { }
}
虽然你可能觉得你的代码永远不会抛出这个异常或者这异常不重要,不需要处理它,像上面那样忽略异常会在你的代码中留下雷区,将来其他人会踩到。你必须在你的代码中以某种原则的方式处理每个异常。具体的处理视情况而定。._ - (安卓官方代码指南)
指南中关于不要忽略异常的说明在 这里.
2.1.2 不要捕获一般的异常。
你不应该这样做:
try {
someComplicatedIOFunction(); // 可能抛出 IOException
someComplicatedParsingFunction(); // 可能抛出 ParsingException
someComplicatedSecurityFunction(); // 可能抛出 SecurityException
//啊哈,统一处理掉
} catch (Exception e) { //我将捕获所有的异常
handleError(); // 使用一个通用的处理手段!
}
查看不这样做的原因以及要怎么做: 猛戳安卓官方指南之不要捕获一般的异常
2.1.3 不要用finalizer
我们不使用finalizer。它什么时候被调用是没有保证的,甚至它不被调用。大部分情况下,你可以使用良好的异常处理来满足需要在finalizer中做的工作。如果你确实需要它,定义一个 close() 方法(或类似的)然后在文档中明确的指出什么时候这个方法需要被调用。可以查看 InputStream 做为例子.这种情况下,在finalizer中打印一个简短的log信息是恰当的但不是必须的,因为我们不希望log泛滥 ._ - (猛戳安卓官方指南之不要用finalizer)
2.1.4 完全的import语句
反例: import foo.*;
正解: import foo.Bar;
点击 这里 查看更多说明
2.2.1 全局变量定义及命名
全局变量应该定义在文件的头部,遵循下面的命名规则。
译者注:这个规则取自Android Open Source Project代码贡献规范。在程序员的圈子里对于要不要前缀这个问题已经吵翻天了。我在使用greendao的时候使用前缀的话,自动生成的getter/setter会是getMxxx/setMxxx这样难看的方法。很多人也觉得这个命名规则没有意义。stackOverFlow 还有 这里 ,以及一本教你怎么写出整洁代码的书中如是说:
“我觉得如今这些前缀没有意义,尤其是在你的APP中!你的类和方法应该尽量的小,而且你应该使用代码高亮的编辑环境,使得成员变量易于分辨。再者,人们快速适应忽略了前缀或后缀来看名字的有意义部分。我们阅读代码越多,看到前后缀越少。渐渐地,前缀就变成了旧代码看不到的线索和标记。——代码整洁之道(Clean.Code).Robert.C.Martin”
例子:
public class MyClass {
public static final int SOME_CONSTANT = 42;
public int publicField;
private static MyClass sSingleton;
int mPackagePrivate;
private int mPrivate;
protected int mProtected;
}
2.2.3把首字母缩写当做一个单词来看
2.2.4 使用空格缩进
使用四个空格做代码块缩进:
if (x == 1) {
x++;
}
换行时使用8个空格缩进:
Instrument i =
someLongExpression(that, wouldNotFit, on, one, line);
2.2.5 使用标准的大括号风格
大括号的开始跟代码同一行
class MyClass {
int func() {
if (something) {
// ...
} else if (somethingElse) {
// ...
} else {
// ...
}
}
}
条件语句使用大括号包住,除非条件体只有一行。
如果条件及只有一行条件体,而且没被换行,大括号是不必的。
if (condition) body();
这是不好的:
if (condition)
body(); // 不好的,没有大括号包围!
2.2.6 注解
2.2.6.1 注解实践规范
根据安卓代码风格指南,一些Java内置的注解标准的实践规范有:
关于注解的更多指南可以查看这里.
2.2.6.2 注解风格
类,方法及构造器
当注解被应用到一个类,方法或者构造函数时候,注解在代码注释之后,一行一个注解
/* 这是这个类的注解 */
@AnnotationA
@AnnotationB
public class MyAnnotatedClass { }
全局变量
全局变量的注解应该在同一行列出。除非这一行超过了最大字数了。
@Nullable @Mock DataManager mDataManager;
2.2.7 限制变量范围
变量的使用范围应该限制到最小(Effective Java 条目 29)。这样做,你可以为你的代码增加可读性和可维护性,减少可能的错误。每个变量应该在最内层的使用到的它代码块中定义
局部变量应该在第一次用到他们的时候定义。几乎每个局部变量都应该初始化。如果你没有足够的信息去初始化一个变量,你应该延迟声明这个变量,直到你有足够的初始化信息。._ - (安卓代码风格指南)
2.2.8 排序import语句
如果你使用IDE,如Android Studio,你不必担心这些规则,这些IDE已经遵循这些规则。如果你不用IDE,往下看这些规则:
import 安卓框架的
Import 来自第三方的(com, junit, net, org)
java 以及 javax
同一个项目的 imports
为了保持跟IDE的设置一致,这些imports应该是这样的:
首字母分组排序,大写的字母在小写的字母前面(如Z在a前面)。
每个主要分组 (android, com, junit, net, org, java, javax)间应该有一行空行。
更多信息查看这里
2.2.9 日志(Loging)指南
使用 Log 类提供的日志方法来打印错误信息或对开发者分辨问题有用的其他信息: