代码中的命名严禁使用拼音与英文混合的方式,更不容许直接使用中文的方式。java
com
└── domain
└── app
├── App.java 定义 Application 类
├── Config.java 定义配置数据(常量)
├── Activity
│ ├── HomeActivity
│ ├── LoginActivity
│ ├── AboutActivity
├── base 基础组件
├── custom_view 自定义视图
├── data 数据处理
│ ├── DataManager.java 数据管理器
| ├── Aes.java Aes数据加密解密
│ ├── local 来源于本地的数据,好比 SP,Database,File
│ ├── model 定义 model(数据结构以及 getter/setter、compareTo、equals 等等,不含复杂操做)
│ └── remote 来源于远端的数据
├── feature 功能
│ ├── feature0 功能 0(搜索垃圾分类)
│ │ ├── feature0Fragment.java
│ │ ├── xxAdapter.java
│ │ └── ... 其余 class
| ├── feature1 功能 1(获取垃圾搜索热点)
│ │ ├── feature1Fragment.java
│ │ ├── xxAdapter.java
│ │ └── ... 其余 class
| ├── feature2 功能 2(app启动时同步最新垃圾分类数据)
│ │ ├── feature1Fragment.java
│ │ ├── xxAdapter.java
│ │ └── ... 其余 class
│ └──....其余功能
├── injection 依赖注入
├── util 工具类(例如网络请求,数据上传)
└── widget 小部件
复制代码
常见类命名格式数据库
类 | 描述 | 例如 |
---|---|---|
Activity 类 | Activity 为后缀标识 | 主页面类 HomeActivity |
Adapter 类 | Adapter 为后缀标识 | 新闻详情适配器 NewsDetailAdapter |
解析类 | Parser 为后缀标识 | 首页解析类 HomePosterParser |
工具方法类 | Utils 或 Manager 为后缀标识 | 打印工具类:PrinterUtils |
数据库类 | 以 DBHelper 后缀标识 | 新闻数据库:NewsDBHelper |
Service 类 | 以 Service 为后缀标识 | 时间服务 TimeService |
BroadcastReceiver 类 | 以 Receiver 为后缀标识 | 推送接收 JPushReceiver |
ContentProvider 类 | 以 Provider 为后缀标识 | ShareProvider |
自定义的共享基础类 | 以 Base 开头 | BaseActivity, BaseFragment |
常见方法命名数组
方法 | 说明 |
---|---|
initXX() | 初始化相关方法,例:初始化布局 initView() |
isXX() checkXX() | 方法返回boolean类型 |
getXXX() | 返回某个值的方法 |
setXXX() | 设置某个属性值 |
handleXXX() processXXX() | 对数据进行处理的方法 |
displayXXX() showXX() | 显示提示框或者消息提示 |
updateXX() | 更新数据 |
saveXXX() | 保存数据 |
clearXXX() | 清除数据 |
removeXXX() | 移除数据或者视图等,如:removeView() |
drawXXX() | 绘制数据或者效果相关等 |
static final int VERSION = 1;
static final String VERSION_NAME "hello world";
复制代码
很是量字段名以 lowerCamelCase 风格的基础上改造为以下风格: 基本结构为 scopeVariableNameType 。bash
例如:网络
public class MyClass {
public int publicField;
private static MyClass sSingleton;
int mPackagePrivate;
private int mPrivate;
protected int mProtected;
}
复制代码
使用 1 个字符前缀来表示做用范围,1 个字符的前缀必须小写,前缀后面是由表意性强的一个单词或多个单词组成的名字,并且每一个单词的首写字母大写,其它字母小写,这样保证了对变量名可以进行正确的断句。数据结构
为了不控件和普通成员变量混淆以及更好地表达意思,全部用来表达控件的成员变量统一加上控件缩写做为前缀app
UI控件缩写表dom
名称 | 缩写 |
---|---|
Button | btn |
CheckBox | cb |
EditText | et |
FrameLayout | fl |
GridView | gv |
ImageButton | ib |
ImageView | iv |
LinearLayout | ll |
ListView | lv |
ProgressBar | pb |
RadioButtion | rb |
RecyclerView | rv |
RelativeLayout | rl |
ScrollView | sv |
SeekBar | sb |
Spinner | spn |
TextView | tv |
ToggleButton | tb |
VideoView | vv |
WebView | wv |
变量名中可能会出现量词,咱们须要建立统一的量词,他们更容易理解,也更容易搜索。 例如: mFirstBook、 mPreBook 、 curBook 。ide
量词列表 | 量词后缀说明 |
---|---|
First | 一组变量中的第一个 |
Last | 一组变量中的最后一个 |
Next | 一组变量中的下一个 |
Pre | 一组变量中的上一个 |
Cur | 一组变量中的当前变量 |
左大括号不单独占一行,与其前面的代码位于同一行:函数
class MyClass {
int func() {
if (something) {
// ...
} else if (somethingElse) {
// ...
} else {
// ...
}
}
}
复制代码
须要在条件语句周围添加大括号。例外状况整个条件语句适合放在同一行,那么能够将其所有放在一行上。例如,咱们接受一下样式:
if (condition) {
body();
}
复制代码
也能够接受一下样式:
if (condition) body();
复制代码
但不接受一下样式:
if (condition)
body();
复制代码
推荐使用以下的排序顺序:
public class MainActivity extends Activity {
private static final String TAG = MainActivity.class.getSimpleName();
private String mTitle;
private TextView mTextViewTitle;
@Override
public void onCreate() {
...
}
public void setTitle(String title) {
mTitle = title;
}
private void setUpView() {
...
}
static class AnInnerClass {
}
}
复制代码
若是类继承于Android组件例如:Activity,那么把重写函数按照他们的生命周期进行排序是一个很是好的习惯。例如:
public class MainActivity extends Activity {
//Order matches Activity lifecycle
@Override
public void onCreate() {}
@Override
public void onResume() {}
@Override
public void onPause() {}
@Override
public void onDestroy() {}
}
复制代码
在Android开发过程当中, Context 在函数参数中是再常见不过的了,咱们最好把 Context 做为函数的第一个参数。
相反,咱们回调接口应该做为其最后一个参数。
例如:
// Context always goes first
public User loadUser(Context context, int userId);
// Callbacks always go last
public void loadUserAsync(Context context, int userId, UserCallback callback);
复制代码
Android SDK中的不少类都用到了键值对函数,好比 SharedPreferences 、 Bundle 、 Intent ,因此,即使是一个小应用,咱们最终也不得不编写大量的字符串常量。
当咱们用到这些类时,必须将他们的将定义为 static final 字段,而且遵循如下指示做为前缀。
类 | 字段名前缀 |
---|---|
SharedPreferences | PREF_ |
Bundle | BUNDLE_ |
Fragment Arguments | ARGUMENT_ |
Intent Extra | EXTRA_ |
Intent Action | ACTION_ |
说明:虽然 Fragment.getArguments() 获得的也是 Bundle ,但由于这是 Bundle 的经常使用用法,因此特地为此定义一个不一样的前缀。
例如:
// 注意:字段的值与名称相同以免重复问题
static final String PREF_EMAIL = "PREF_EMAIL";
static final String BUNDLE_AGE = "BUNDLE_AGE";
static final String ARGUMENT_USER_ID = "ARGUMENT_USER_ID";
// 与意图相关的项使用完整的包名做为值的前缀
static final String EXTRA_SURNAME = "com.myapp.extras.EXTRA_SURNAME";
static final String ACTION_OPEN_USER = "com.myapp.action.ACTION_OPEN_USER";
复制代码
当 Activity 或 Fragment 传递数据经过 Intent 或 Bundle 时,不一样值的键须遵循上一条所说起到的。
当 Activity 或 Fragment 启动须要传递参数时,那么它须要提供一个 public static 的函数来帮助启动或建立它。
这方面,AS 已帮你写好了相关的 Live Templates,启动相关 Activity 的只须要在其内部输入 starter 便可生成它的启动器,以下所示:
public static void start(Context context, User user) {
Intent starter = new Intent(context, MainActivity.class);
starter.putParcelableExtra(EXTRA_USER, user);
context.startActivity(starter);
}
复制代码
同理,启动相关 Fragment 在其内部输入 newInstance 便可,以下所示:
public static MainFragment newInstance(User user) {
Bundle args = new Bundle();
args.putParcelable(ARGUMENT_USER, user);
MainFragment fragment = new MainFragment();
fragment.setArguments(args);
return fragment;
}
复制代码
int longName = anotherVeryLongVariable + anEvenLongerOne - thisRidiculousLongOne
+ theFinalOne;
复制代码
int longName =
anotherVeryLongVariable + anEvenLongerOne - thisRidiculousLongOne + theFinalOne;
复制代码
当同一行中调用多个函数时,对每一个函数的调用都应该在行的一行中,咱们把换行符插入在 . 以前。
例如:
Picasso.with(context).load("https://blankj.com/images/avatar.jpg").into(ivAvatar);
复制代码
应该使用以下规则:
Picasso.with(context)
.load("https://blankj.com/images/avatar.jpg")
.into(ivAvatar);
复制代码
当一个方法有不少参数或者参数很长的时候,咱们应该在每一个 , 后面进行换行。 好比:
loadPicture(context, "https://blankj.com/images/avatar.jpg", ivAvatar, "Avatar of the user", clickListener);
复制代码
应该使用以下规则:
loadPicture(context,
"https://blankj.com/images/avatar.jpg",
ivAvatar,
"Avatar of the user",
clickListener);
复制代码
RxJava 的每一个操做符都须要换新行,而且把换行符插入在 . 以前。
例如:
public Observable<Location> syncLocations() {
return mDatabaseHelper.getAllLocations()
.concatMap(new Func1<Location, Observable<? extends Location>>() {
@Override
public Observable<? extends Location> call(Location location) {
return mRetrofitService.getLocation(location.id);
}
})
.retry(new Func2<Integer, Throwable, Boolean>() {
@Override
public Boolean call(Integer numRetries, Throwable throwable) {
return throwable instanceof RetrofitError;
}
});
}
复制代码
每一个类完成后应该有做者姓名和联系方式的注解,对本身的代码负责。 例如:
/**
* author : Blankj
* time : 2019/07/13
* desc : xxxx 描述
* version: 1.0
*/
public class WelcomeActivity {
...
}
复制代码
具体能够在AS在那个本身配置,进入 Settings -> Editor -> File and Code Templates -> Includes -> File Header,输入
/**
* author : ${USER}
* time : ${YEAR}/${MONTH}/${DAY}
* desc :
* version: 1.0
*/
复制代码
这样可在每次新建类的时候自动加上该头注释。
每个成员方法(包括自定义成员方法、覆盖方法、属性方法)的方法头都必须作方法头注释,在方法前一行输入 /** + 回车 或者设置 Fix doc comment(Settings -> Keymap -> Fix doc comment)快捷键,AS 便会帮你生成模板,咱们只须要补全参数便可,以下所示。
/**
* bitmap 转 byteArr
*
* @param bitmap bitmap 对象
* @param format 格式
* @return 字节数组
*/
public static byte[] bitmap2Bytes(Bitmap bitmap, CompressFormat format) {
if (bitmap == null) return null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(format, 100, baos);
return baos.toByteArray();
}
复制代码
块注释与其周围的代码在同一缩进级别。它们能够是 /* ... */ 风格,也能够是 // ... 风格(// 后最好带一个空格)。对于多行的 /* ... */ 注释,后续行必须从 * 开始, 而且与前一行的 * 对齐。如下示例注释都是 OK 的。
/*
* This is
* okay.
*/
// And so
// is this.
/* Or you can
* even do this. */
复制代码
AS 已帮你集成了一些注释模板,咱们只须要直接使用便可,在代码中输入 todo、fixme 等这些注释模板,回车后便会出现以下注释。
// TODO: 17/3/14 须要实现,但目前还未实现的功能的说明
// FIXME: 17/3/14 须要修正,甚至代码是错误的,不能工做,须要修复的说明
复制代码