文档章节

Android 指南

渊泉如渊
 渊泉如渊
发布于 2016/10/12 22:19
字数 3798
阅读 42
收藏 0

原文:https://github.com/ribot/android-guidelines/blob/master/project_and_code_guidelines.md

1.项目指南

1.1 项目结构

新项目应该遵循 Android Gradle plugin 用户指导定义的Android Gradle项目结构。开始以ribot Boilerplate项目是很好的参考。

1.2 文件命名

1.2.1 类文件

类名称用驼峰类拼写。

对于扩展Android组件的类,类的名称应该以组件的名称作为结束;例如:SignInActivity,SignInFragment,ImageUploaderService,ChangePasswordDialog。

1.2.2 资源文件

资源文件用lowercase_underscore命名。

1.2.2.1 Drawable 文件

Drawable文件命名约定:

资源类型前缀例子
Action barab_ab_stacked.9.png
Buttonbtn_btn_send_pressed.9.png
Dialogdialog_dialog_top.9.png
Dividerdivider_divider_horizontal.9.png
Iconic_ic_star.png
Menumenu_menu_submenu_bg.9.png
Notificationnotification_notification_bg.9.png
Tabstab_tab_pressed.9.png

icons的命名约定(来自Android iconography guidelines):

资源类型前缀例子
Iconsic_ic_star.png
Launcher iconsic_launcheric_launcher_calendar.png
Menu icons and Action Bar iconsic_menuic_menu_archive.png
Status bar iconsic_stat_notifyic_stat_notify_msg.png
Tab iconsic_tabic_tab_recent.png
Dialog iconsic_dialogic_dialog_info.png

selector states的命名约定:

资源类型前缀例子
Normal_normalbtn_order_normal.9.png
Pressed_pressedbtn_order_pressed.9.png
Focused_focusedbtn_order_focused.9.png
Disabled_disabledbtn_order_disabled.9.png
Selected_selectedbtn_order_selected.9.png
1.2.2.2 布局文件

布局文件应该与它们打算用于的Android组件的名称匹配,但将顶层组件名称移动到开头。例如:我们将要为SignInActivity创建布局文件,那么布局文件的名字应该为activity_sign_in.xml

组件类名称布局文件名称
ActivityUserProfileActivityactivity_user_profile.xml
FragmentSignUpFragmentfragment_sign_up.xml
DialogChangePasswordDialogdialog_change_password.xml
AdapterView item---item_person.xml
Partial layout---partial_stats_bar.xml

稍微不同的情况是,当我们创建一个布局,要通过一个“Adapter”来适配,例如填充一个“ListView”。在这种情况下,布局的名称应以item_开头。

请注意,有些情况下,这些规则将无法应用。 例如,当创建旨在作为其他布局的一部分的布局文件时。 在这种情况下,您应该使用前缀“partial_”。

1.2.2.3 目录文件

与布局文件类似,菜单文件应与组件的名称匹配。 例如,如果我们定义将要在UserActivity中使用的菜单文件,那么文件的名称应该是activity_user.xml

一个好的做法是不要将“menu”一词作为名称的一部分,因为这些文件已经位于menu目录中。

1.2.2.4 Values 文件

values文件夹中的资源文件应为__plural__,例如 strings.xmlstyles.xmlcolors.xmldimensions.xmlattrs.xml

2.代码指南

2.1 Java语言规则

2.1.1 不要忽略异常

您绝不能做以下事情:

void setServerPort(String value) {
    try {
        serverPort = Integer.parseInt(value);
    } catch (NumberFormatException e) { }
}

虽然你可能认为你的代码永远不会遇到这种错误或者它不重要而不处理,在你的代码中忽略上面的代码就是挖了让别人查找一整天的坑。因此,你必须用一些原则的方式来处理你代码中的每一个异常。具体的处理方法因情况而异。-(Android code style guidelines)

查看备选方案点击我

2.1.2 不要捕获通用异常

你不要这样做:

try {
    someComplicatedIOFunction();        // may throw IOException
    someComplicatedParsingFunction();   // may throw ParsingException
    someComplicatedSecurityFunction();  // may throw SecurityException
    // phew, made it all the way
} catch (Exception e) {                 // I'll just catch all exceptions
    handleError();                      // with one generic handler!
}

查看原因和一些备选方案点击我

2.1.3 不要使用finalizer

我们不使用finalizer。对于什么时候调用终结器,甚至什么时候调用终结器都没有保证。 在大多数情况下,您可以从具有良好异常处理的终结器中完成所需的操作。 如果你绝对需要它,定义一个close()方法(或类似的),并准确记录该方法需要被调用。 参见InputStream例子。 在这种情况下,只要不期望洪水日志,就可以打印来自终结器的短日志消息,但不是必需的。- (Android code style guidelines)

2.1.4 完全限定导入

这是不好的:import foo.*;

这是好的:import foo.Bar;

查看更多信息 点击我

2.2 Java风格规则

2.2.1 字段定义和命名

字段应该定义在 文件的顶部 ,并且它们应该遵循下面列出的命名规则。

  • 私有,非静态字段名以__m__开头。
  • 私有,静态字段名以__s__开头。
  • 其他字段以小写字母开头。
  • 静态最终字段(常量)为ALL_CAPS_WITH_UNDERSCORES。

例如:

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 把缩写词作为词

XmlHttpRequestXMLHTTPRequest
getCustomerIdgetCustomerID
String urlString URL
long idlong ID

2.2.4 使用空格缩进

对代码块使用__四个空格__缩进:

if (x == 1) {
    x++;
}

对换行使用__八个空格__缩进:

Instrument i =
        someLongExpression(that, wouldNotFit, on, one, line);

2.2.5 使用标准括号风格

大括号与它们之前的代码在同一行上。

class MyClass {
    int func() {
        if (something) {
            // ...
        } else if (somethingElse) {
            // ...
        } else {
            // ...
        }
    }
}

需要括号在语句周围,除非条件和主体适合在一行。

如果条件和主体在一行上合适,并且该线小于最大行长度,则不需要括号,e.g.

if (condition) body();

这是 不好的:

if (condition)
    body();  // bad!

2.2.6 注释风格

类,方法和构造函数

当给类,方法或构造函数添加注释时,它们会在注释文档之后列出,并应显示为__每行一个注释__。

/* This is the documentation block about the class */
@AnnotationA
@AnnotationB
public class MyAnnotatedClass { }

字段

当给字段添加注释时,它们应该和字段__在同一行__,除非达到行最大长度。

@Nullable @Mock DataManager mDataManager;

2.2.7 限制变量作用域

局部变量的范围应该保持最小(Effective Java Item 29)。 通过这样做,您可以提高代码的可读性和可维护性,并减少出错的可能性。 每个变量应该在包含变量所有使用的最内层块中声明。

局部变量应该在它们首次使用时声明。 几乎每个局部变量声明都应该包含一个初始化器。 如果你还没有足够的信息来初始化一个变量,你应该推迟声明,直到你这样做。- (Android code style guidelines)

2.2.8 排列import语句

如果您使用的是IDE(如Android Studio),则不必担心,因为您的IDEA已经遵守规则。 如果没有,看看下面。

import语句的顺序是:

  1. 导入Android
  2. 导入第三方类库 (com, junit, net, org)
  3. java 和 javax
  4. 导入相同项目

要完全匹配IDE设置,导入应该为:

  • 在每个分组中按字母顺序排列,大写字母前加小写字母(例如,a前面的Z)。
  • 在每个主要分组(android,com,junit,net,org,java,javax)之间应该有一个空白行。

更多信息 点我

2.2.9 日志指南

使用Log类提供的日志记录方法打印错误消息或其他可能有助于开发人员识别问题的信息:

  • Log.v(String tag, String msg) (verbose)
  • Log.d(String tag, String msg) (debug)
  • Log.i(String tag, String msg) (information)
  • Log.w(String tag, String msg) (warning)
  • Log.e(String tag, String msg) (error)

作为一般规则,我们使用类名作为标记,我们将其定义为文件顶部的“static final”字段。 例如:

public class MyClass {
    private static final String TAG = MyClass.class.getSimpleName();

    public myMethod() {
        Log.e(TAG, "My error message");
    }
}

在发布正式版本时__务必__禁用VERBOSE和DEBUG日志。 还建议禁用INFORMATION,WARNING和ERROR日志,但如果您认为这些日志可能有助于识别发行版本上的问题,则可能需要启用它们。 如果您决定让它们保持启用状态,您必须确保他们没有泄露私人信息,例如电子邮件地址,用户ID等。

仅在调试版本上显示日志:

if (BuildConfig.DEBUG) Log.d(TAG, "The value of x is " + x);

2.2.10 类成员排序

没有单一正确的解决方案,但使用__逻辑__和__一致性__的顺序,将提高代码的学习性和可读性。 建议使用以下顺序:

  1. 常量
  2. 字段
  3. 构造函数
  4. 覆盖方法和回调(公共或私有)
  5. 公共方法
  6. 私有方法
  7. 内部类或接口

例如:

public class MainActivity extends Activity {

	private String mTitle;
    private TextView mTextViewTitle;

    public void setTitle(String title) {
    	mTitle = title;
    }

    @Override
    public void onCreate() {
        ...
    }

    private void setUpView() {
        ...
    }

    static class AnInnerClass {

    }

}

如果你的类继承一个__Android 组件__(例如一个Activity或者一个Fragment),根据覆盖方法是一个很好的排序方法以便它们__匹配组件的生命周期__。例如,你有一个Activity实现onCreate(), onDestroy(), onPause() and onResume(),那么正确的顺序是:

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() {}

}

2.2.11 方法中的参数排序

当为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);

2.2.13 字符串常量,命名和值

Android SDK的许多元素(如“SharedPreferences”,“Bundle”或“Intent”)使用键值对方法,因此即使对于小型应用程序,最终也需要写入大量的String常量。

当使用这些组件其中之一时,__必须__将这些键定义为static final字段,并且它们应该如下所示进行前缀。

元素字段名前缀
SharedPreferencesPREF_
BundleBUNDLE_
Fragment ArgumentsARGUMENT_
Intent ExtraEXTRA_
Intent ActionACTION_

注意Fragment的arguments -Fragment.getArguments()- 也是一个Bundle。 然而,因为这是一个很常见使用的Bundles,我们为它们定义一个不同的前缀。

例子:

// Note the value of the field is the same as the name to avoid duplication issues
static final String PREF_EMAIL = "PREF_EMAIL";
static final String BUNDLE_AGE = "BUNDLE_AGE";
static final String ARGUMENT_USER_ID = "ARGUMENT_USER_ID";

// Intent-related items use full package name as value
static final String EXTRA_SURNAME = "com.myapp.extras.EXTRA_SURNAME";
static final String ACTION_OPEN_USER = "com.myapp.action.ACTION_OPEN_USER";

2.2.14 Fragments和Activities中的Arguments

当数据通过“Intent”或“Bundle”传递到“Activity”或“Fragment”中时,不同值的键__必须__遵循上一节中描述的规则。

当一个ActivityFragment需要参数时,它应该提供一个public static方法,便于创建相关的IntentFragment

在Activity的情况下,方法通常被称为getStartIntent()

public static Intent getStartIntent(Context context, User user) {
	Intent intent = new Intent(context, ThisActivity.class);
	intent.putParcelableExtra(EXTRA_USER, user);
	return intent;
}

对于Fragments,它被命名为newInstance(),并处理带有正确参数的Fragment的创建:

public static UserFragment newInstance(User user) {
	UserFragment fragment = new UserFragment;
	Bundle args = new Bundle();
	args.putParcelable(ARGUMENT_USER, user);
	fragment.setArguments(args)
	return fragment;
}

Note 1:这些方法应该放在类的顶部onCreate()之前。

Note 2:如果我们提供上面描述的方法,extras和arguments的键应该是private,因为它们不需要暴露在类的外面。

2.2.15 行长度限制

代码每行不应超过__100个字符__。 在行的长度超过这个限制,通常有两个选项来减少其长度:

  • 提取局部变量或方法(首选)。
  • 应用换行将单行划分为多个。

有两个__异常__,其中可能有行超过100:

  • 不能分割的线,例如, 在评论中的长URL。
  • packageimport语句。
2.2.15.1 换行策略

没有一个精确的准则说明如何换行,并且通常不同的解决方案是有效的。 然而,有一些规则可以应用于常见的情况。

在操作符处间断

当行在操作符处间断时,断点应该是操作符__在前__。例如:

int longName = anotherVeryLongVariable + anEvenLongerOne - thisRidiculousLongOne
        + theFinalOne;

赋值操作符异常

break at operators规则的一个例外是赋值运算符=,其中换行符应该在运算符__后边__。

int longName =
        anotherVeryLongVariable + anEvenLongerOne - thisRidiculousLongOne + theFinalOne;

方法链情况

当多个方法在同一行中链接时 - 例如,当使用Builders时 - 每个调用的一个方法都应该在它自己的行中,并且.在前。

Picasso.with(context).load("http://ribot.co.uk/images/sexyjoe.jpg").into(imageView);
Picasso.with(context)
        .load("http://ribot.co.uk/images/sexyjoe.jpg")
        .into(imageView);

长参数情况

当一个方法有很多参数或者它的参数很长时,我们应该在每个逗号后间断。

loadPicture(context, "http://ribot.co.uk/images/sexyjoe.jpg", mImageViewProfilePicture, clickListener, "Title of the picture");
loadPicture(context,
        "http://ribot.co.uk/images/sexyjoe.jpg",
        mImageViewProfilePicture,
        clickListener,
        "Title of the picture");

2.2.16 RxJava链式样

Rx链的操作符需要换行。 每个操作符必须进入新行,该行应该在.之前断开。

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;
                 }
            });
}

2.3 XML风格规则

2.3.1 使用自闭标签

当XML元素没有包含任何内容时,__必须__使用自闭标签。

这是好的:

<TextView
	android:id="@+id/text_view_profile"
	android:layout_width="wrap_content"
	android:layout_height="wrap_content" />

这是 差的

<!-- Don\'t do this! -->
<TextView
    android:id="@+id/text_view_profile"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" >
</TextView>

2.3.2 资源命名

资源ID和名称用__小写_下划线__。

2.3.2.1 ID命名

ID应以元素的名称的小写下划线为前缀。 例如:

元素前缀
TextViewtext_
ImageViewimage_
Buttonbutton_
Menumenu_

ImageView 例子:

<ImageView
    android:id="@+id/image_profile"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

Menu 例子:

<menu>
	<item
        android:id="@+id/menu_done"
        android:title="Done" />
</menu>
2.3.2.2 字符串

字符串名称以标识其所属的前缀开头。 例如registration_email_hintregistration_name_hint。 如果字符串__不属于__任何部分,则应遵循以下规则:

前缀描述
error_一个错误的消息
msg_一个定期信息消息
title_标题,例如,Dialog标题
action_一个行为,例如 "保存" 或 "创建"
2.3.2.3 样式和主题

除非资源的其余部分,样式名称写在_ UpperCamelCase _。

2.3.3 属性排序

作为一般规则,您应该尝试将类似的属性分组在一起。 最常见属性的好方法的排序是:

  1. View Id
  2. Style
  3. 布局宽度和布局高度
  4. 其他布局属性,按字母顺序排序
  5. 剩余属性,按字母顺序排序

2.4 测试样式规则

2.4.1 单元测试

测试类应该匹配测试所针对的类的名称,后跟Test。 例如,如果我们创建一个包含“DatabaseHelper”测试的测试类,我们应该命名为DatabaseHelperTest。

测试方法使用“@ Test”注释,通常应该从被测试方法的名称开始,然后是前提条件 和/或 预期行为。

  • 模版:@Test void method NamePrecondition Expected Behavior()
  • 示例:@Test void signInWithEmptyEmailFails()

如果没有它们的测试足够清楚,可能不总是需要前提条件 和/或 预期行为。

有时一个类可能包含大量的方法,同时需要对每个方法进行多次测试。 在这种情况下,建议将测试类拆分为多个。 例如,如果DataManager包含很多方法,我们可能需要将它分成DataManagerSignInTestDataManagerLoadUsersTest等。一般来说,你将能够看到什么测试属于一起,因为他们有共同的测试用例

2.4.2 UI自动化测试

每个Espresso测试类通常定位一个Activity,因此名称应该匹配目标Activity的名称,后跟Test,例如。 SignInActivityTest

当使用Espresso API时,通常将链接方法放在新行中。

onView(withId(R.id.view))
        .perform(scrollTo())
        .check(matches(isDisplayed()))
Copyright 2015 Ribot Ltd.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

© 著作权归作者所有

渊泉如渊

渊泉如渊

粉丝 7
博文 33
码字总数 25641
作品 0
郑州
Android工程师
私信 提问
关于Android资源站

谷歌开发者中国站 Google Developers 中国网站是特别为中国开发者而建立的,它汇集了 Google 为全球开发者所提供的开发技术资源,包括 API 文档、开发案例、技术培训的视频。 Android官方开发...

请天点
2016/12/14
651
0
Android 内容提供器---创建内容提供器(<provider>元素)

像Activity和Service组件一样,ContentProvider子类必须在它的应用程序的清单文件中使用元素来定义。Android系统要从这个元素中获取以下信息: 1. 授权(android:authorities) 在系统中标识...

长平狐
2012/10/16
69
0
2017 年回顾:Android

2017 对于 Android 来说是了不起的一年。在这一年中,Android 发布了很多重大的公告,包括支持 Kotlin 这一领人振奋的新语言,以及使用 Neural 网络 API 和 ARCore 构建智能交互式应用等。 ...

oschina
2018/01/15
3K
3
欢迎加入 Android Q 测试版计划!

欢迎加入 Android Q 测试版计划!此计划将为您提供针对下一个 Android 版本实现您的应用兼容性以及开发应用所需的一切。它是一款免费软件,您只需下载测试版 SDK 和工具即可立即使用。 硬件和...

Android_开发者
04/18
0
0
Android 4.4.2 KitKat 发布,以及如何安装

Android 4.4.1 发布仅仅几天后,Google 已经为 Nexus 设备准备好了 4.4.2 版本。该版本包含 Nexus 5 摄像头的显著改进,其他主要是重要 bug 的修复。 Android 4.4.2 修复了 VM Indicator 的清...

oschina
2013/12/10
8.4K
13

没有更多内容

加载失败,请刷新页面

加载更多

64.监控平台介绍 安装zabbix 忘记admin密码

19.1 Linux监控平台介绍 19.2 zabbix监控介绍 19.3/19.4/19.6 安装zabbix 19.5 忘记Admin密码如何做 19.1 Linux监控平台介绍: 常见开源监控软件 ~1.cacti、nagios、zabbix、smokeping、ope...

oschina130111
今天
13
0
当餐饮遇上大数据,嗯真香!

之前去开了一场会,主题是「餐饮领袖新零售峰会」。认真听完了餐饮前辈和新秀们的分享,觉得获益匪浅,把脑子里的核心纪要整理了一下,今天和大家做一个简单的分享,欢迎感兴趣的小伙伴一起交...

数澜科技
今天
7
0
DNS-over-HTTPS 的下一代是 DNS ON BLOCKCHAIN

本文作者:PETER LAI ,是 Diode 的区块链工程师。在进入软件开发领域之前,他主要是在做工商管理相关工作。Peter Lai 也是一位活跃的开源贡献者。目前,他正在与 Diode 团队一起开发基于区块...

红薯
今天
10
0
CC攻击带来的危害我们该如何防御?

随着网络的发展带给我们很多的便利,但是同时也带给我们一些网站安全问题,网络攻击就是常见的网站安全问题。其中作为站长最常见的就是CC攻击,CC攻击是网络攻击方式的一种,是一种比较常见的...

云漫网络Ruan
今天
12
0
实验分析性专业硕士提纲撰写要点

为什么您需要研究论文的提纲? 首先当您进行研究时,您需要聚集许多信息和想法,研究论文提纲可以较好地组织你的想法, 了解您研究资料的流畅度和程度。确保你写作时不会错过任何重要资料以此...

论文辅导员
今天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部