A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© s952397683 中级黑马   /  2016-9-21 22:43  /  444 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52602487
前言:Android中一些开发规范,避免给自己和别人少留坑。
一、工程相关
  • 1.1 工程结构
    当进行提交代码的工作时,工程应该保持如下的目录结构:
//create by 逆流的鱼yuiop on 2016/9/21//blog地址:http://blog.csdn.net/hejjunlin- src/androidTest- src/test- src/commonTest- src/main- androidTest - 功能测试目录- test - 单元测试目录- commonTest - 为AndroidTest & Test 提供的共享测试代码的目录- main - 应用代码目录
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

当你修改或者增加新功能的时候,工程结构依然应该保持如上的样子。
使用如上的工程结构可以让我们的应用代码从相关的测试代码中分离出来。
CommonTest目录使得我们的功能测试和单元测试可以共享部分代码,比如mock model creation and dagger test configuration classes.
  • 1.2 文件命名
    • 1.2.1 类文件
      任何定义的类都应该使用驼峰命名格式,比如:
//create by 逆流的鱼yuiop on 2016/9/21//blog地址:http://blog.csdn.net/hejjunlinAndroidActivity, NetworkHelper, UserFragment, PerActivity
  • 1
  • 2
  • 3

任何继承自android组件的类都应该使用组件名称来结尾,比如:
//create by 逆流的鱼yuiop on 2016/9/21//blog地址:http://blog.csdn.net/hejjunlinUserFragment, SignUpActivity, RateAppDialog, PushNotificationServer, NumberView
  • 1
  • 2
  • 3

  • 使用驼峰格式命名易于阅读。
  • 用android组件名称结尾的继承类能够清楚的标识出类的用途,比如,如果要去查找修改RegistrationDialog时,那么这个命名使得定位这个类文件非常方便。

    • 1.2.2 资源文件
      • 当命名资源文件时,应该只使用小写字母和下划线替代空格,例如:
        activity_main, fragment_user, item_post
        在你查找布局文件时,这样命名同样使得定位文件很方便。
      • 在使用android studio中,布局的package中的文件是按字母顺序排列的,这样意味activity,fragment和其他的layout是按组分类放置的,所以你知道从哪里去开始找一个文件了。
      • 不仅如此,用组件名称开头的布局文件可以很清晰的表示这个布局文件是被那类组件使用。
  • 1.2.2.1 Drawable 文件

    • Drawable资源文件应该使用“ic_”前缀后跟上尺寸以及资源的颜色信息
      For example, white accept icon sized at 24dp would be named:
      比如,白色的24dp大小的用于接受动作的图标应该命名如下:
      ic_accept_24dp_white
      黑色用于取消动作的48dp大小的图标命名:
      ic_cancel_48dp_black
      我们使用这样的命名约定方便使用命名来组织drawable资源文件
    • 如果命名中没有颜色和尺寸信息,那么开发者还需要打开drawable文件去查看这些信息。所以这样可以节约我们时间.其他的drawable文件应该使用对应的前缀,如下:
//create by 逆流的鱼yuiop on 2016/9/21
//blog地址:http://blog.csdn.net/hejjunlin
TypePrefixExample
Selectorselector_selector_button_cancel
Backgroundbg_bg_rounded_button
Circlecircle_circle_white
Progressprogress_progress_circle_purple
Dividerdivider_divider_grey在Android Studio中这个命名约定依然可以帮助我们将相似的组织到一起
并清晰的标识出这一文件用作什么
比如, 命令一个资源为“button_cancel”不能标识任何信息
这是一个selector资源呢还是一个圆角按钮背景呢?
正确的命名可以去除所有的引起的模糊不清.
在创建selector不同状态资源时,也应该使用对应的命名下标:
//create by 逆流的鱼yuiop on 2016/9/21
//blog地址:http://blog.csdn.net/hejjunlin
StateSuffixExample
Normal_normalbtn_accept_normal
Pressed_pressedbtn_accept_pressed
Focused_focusedbtn_accept_focused
Disabled_disabledbtn_accept_disabled
Selected_selectedbtn_accept_selected使用如上清晰的下标绝对明显的标识出了selector状态资源的作用。
为有颜色和其他标识的资源文件增加下标,使得开发者在打开selector文件时就可以知道不同的selector资源的状态是什么
1.2.2.2 Layout 文件
在命名布局文件时,应该用android组件的名称作为文件名的前缀,比如:
//create by 逆流的鱼yuiop on 2016/9/21
//blog地址:http://blog.csdn.net/hejjunlin
ComponentClass NameLayout Name
ActivityMainActivityactivity_main
FragmentMainFragmentfragment_main
DialogRateDialogdialog_rate
WidgetUserProfileViewview_user_profile
AdapterViewItemN/A item_follower注意:如果要创建的布局文件是有多个不同组件使用的,那么应该使用”layout_”前缀
这样不仅在层级目录中可以很方便的找到文件,
这样也可以帮助我们定义相应的这个layout布局文件归属的类。

1.2.2.3 Menu Files
菜单文件不需要使用“menu_”前缀。
在资源目录下已经有菜单包了,所以这是不必要的。

1.2.2.4 Values Files
所有的资源文件名必须是复数的,比如:
attrs.xml, strings.xml, styles.xml, colors.xml, dimens.xml

二、代码相关
  • 2.1 Java语句规则
    • 2.1.1 绝不要忽略exceptions
      正确的方式是避免没有处理的异常,如下:
//create by 逆流的鱼yuiop on 2016/9/21//blog地址:http://blog.csdn.net/hejjunlinpublic void setUserId(String id) {    try {        mUserId = Integer.parseInt(id);    } catch (NumberFormatException e) { }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

如果这里出现问题,这里不会打印出任何信息,而且也很难debug,只能让人迷惑。
当catch一个异常时,我们总是需要输出error日志到控制台,用于调试,如果必要的话,需要警告用户这个异常。比如:
//create by 逆流的鱼yuiop on 2016/9/21//blog地址:http://blog.csdn.net/hejjunlinpublic void setCount(String count) {    try {        count = Integer.parseInt(id);    } catch (NumberFormatException e) {        count = 0;        Log.e(TAG, "There was an error parsing the count " + e);        DialogFactory.showErrorMessage(R.string.error_message_parsing_count);    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

这里我们有如下的方式处理出错:
  • 显示一个信息给用户,提示他们这里出错了
  • 设置了一个可能的默认值
  • 抛出了一个合适的异常
2.1.2 不要catch最大的异常(Exception):
//create by 逆流的鱼yuiop on 2016/9/21//blog地址:http://blog.csdn.net/hejjunlinpublic void openCustomTab(Context context, Uri uri) {    Intent intent = buildIntent(context, uri);    try {        context.startActivity(intent);    } catch (Exception e) {        Log.e(TAG, "There was an error opening the custom tab " + e);    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

为什么不这样做呢?
在大部分情况下,catch这个大的Exception或者Throwable都是不合适的。(特别是Throwable因为它包含Error的异常。)
这样意味着你没有期望到的最终要捕获的异常(包括RuntimeExceptions像CLassCastException)都被捕获并在应用层进行error处理,这样是很危险的。
如果有人在你调用的代码里添加了一个新的类型的异常,编译器不会帮你认识到你需要处理这个不同的错误类型。这是你代码里很难发现的错误处理方式。
大多数情况下,你不应该用相同的处理方式来处理不同的exception.
如下,catch期望的异常并正确的处理:
//create by 逆流的鱼yuiop on 2016/9/21//blog地址:http://blog.csdn.net/hejjunlinpublic void openCustomTab(Context context, Uri uri) {    Intent intent = buildIntent(context, uri);    try {        context.startActivity(intent);    } catch (ActivityNotFoundException e) {        Log.e(TAG, "There was an error opening the custom tab " + e);    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

2.1.3 组织 exceptions
在异常运行相同的代码的地方,他们应该增加可读性和避免代码复制。比如,你可能会像如下这样处理异常:
//create by 逆流的鱼yuiop on 2016/9/21//blog地址:http://blog.csdn.net/hejjunlinpublic void openCustomTab(Context context, @Nullable Uri uri) {    Intent intent = buildIntent(context, uri);    try {        context.startActivity(intent);    } catch (ActivityNotFoundException e) {        Log.e(TAG, "There was an error opening the custom tab " + e);    } catch (NullPointerException e) {        Log.e(TAG, "There was an error opening the custom tab " + e);    } catch (SomeOtherException e) {        // Show some dialog    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

你可以这样做:
//create by 逆流的鱼yuiop on 2016/9/21//blog地址:http://blog.csdn.net/hejjunlinpublic void openCustomTab(Context context, @Nullable Uri uri) {    Intent intent = buildIntent(context, uri);    try {        context.startActivity(intent);    } catch (ActivityNotFoundException e | NullPointerException e) {        Log.e(TAG, "There was an error opening the custom tab " + e);    } catch (SomeOtherException e) {        // Show some dialog    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

2.1.4 Using try-catch over throw exception
在exception出现的地方使用try-catch块增加代码可读性
在代码中error发生的地方就处理,这样不管是debug还是更改error处理都很容易。

2.1.5 不要使用垃圾回收器
  • 不能保证什么时候垃圾回收器会被调用,也不能保证垃圾回收器将在什么时候调用.
  • 大部分情况下,在有规范的异常处理的情况下,你可以做你需要做的。
    如果你实在需要,定义一个close()方法(或者类似的)并在方法调用时,提醒记得close
  • 以InputStreamfor作为example.
  • 在这种情况下是可以的,但是不需要从垃圾回收器中输出少量日志信息,也不需要输出大量日志.

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马