This is an ongoing documents, which we will continue to add contents.
Meaningful, For Short.
Package names are all lowercase, with consecutive words simply concatenated together (no underscores).
For example, com.example.deepspace
, not com.example.deepSpace
or com.example.deep_space
.
Class names are written in UpperCamelCase.
Class names are typically nouns or noun phrases. For example, Character or ImmutableList. Interface names may also be nouns or noun phrases (for example, List), but may sometimes be adjectives or adjective phrases instead (for example, Readable).
For classes that extend an Android component, the name of the class should end with the name of the component;
For example: SignInActivity
, SignInFragment
, ImageUploaderService
, ChangePasswordDialog
.
Static final fields (constants) are ALL_CAPS_WITH_UNDERSCORES.
Constant names use CONSTANT_CASE: all uppercase letters, with words separated by underscores
Many elements of the Android SDK such as SharedPreferences
, Bundle
, or Intent
use a key-value pair approach so it's very likely that even for a small app you end up having to write a lot of String constants.
When using one of these components, you must define the keys as a static final
fields and they should be prefixed as indicated below.
Element | Field Name Prefix |
---|---|
SharedPreferences | PREF_ |
Bundle | BUNDLE_ |
Fragment Arguments | ARG_ |
Intent Extra | EXTRA_ |
Intent Action | ACTION_ |
Note that the arguments of a Fragment - Fragment.getArguments()
- are also a Bundle. However, because this is a quite common use of Bundles, we define a different prefix for them.
- Private, non-static field names start with m.
- Private, static field names start with s.
- Other fields start with a lower case letter.
- local variable naming with lowerCamelCase
Even when final and immutable, local variables are not considered to be constants, and should not be styled as constants.
Good | Bad |
---|---|
XmlHttpRequest |
XMLHTTPRequest |
getCustomerId |
getCustomerID |
String url |
String URL |
long id |
long ID |
Do not use the public field variables in class.
public class MyClass {
public static final int SOME_CONSTANT = 42;//The name of a constant is capitalized, and points out the full meaning of the word
private static MyClass sSingleton;
int mPackagePrivate;
private int mPrivate;
protected int mProtected;
private TextView mXxxxxTv;
private ImageView mXxxxxIv;
private Dialog mXxxxxDlg;
private Button mXxxxBtn;
private Menu mXxxxMenu;
void test() {
//The first letter is lowercase and the first letter is capitalized.
//Do not use or _ & the first letter.
//Try to use short and meaningful words.
int i= 0;
boolean isFileWallEnable = false;
}
}
// 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"
//Enumeration type,
enum SomeEnum { ENUM_FIRST, ENUM_SENCOND}
//Array
static final String[] NON_EMPTY_ARRAY = {"these", "can", "change"};
Method names are typically verbs or verb phrases. For example, sendMessage or stop.
Underscores may appear in JUnit test method names to separate logical components of the name. One typical pattern is test_, for example testPop_emptyStack. There is no One Correct Way to name test methods.
public class MyClass {
public String getName();
public void setName();
public boolean isFirst();
public Boolean getFirst();
// Bad example
public boolean isNotValidString();
}
Resources file names are written in lowercase_underscore.
Naming conventions for drawables:
Asset Type | Prefix | Example |
---|---|---|
Action bar | ab_ |
ab_stacked.9.png |
Button | btn_ |
btn_send_pressed.9.png |
Dialog | dlg_ |
dlg_top.9.png |
Divider | divider_ |
divider_horizontal.9.png |
Icon | ic_ |
ic_star.png |
Menu | menu_ |
menu_submenu_bg.9.png |
Notification | notify_ |
notify_bg.9.png |
Tabs | tab_ |
tab_pressed.9.png |
Naming conventions for icons (taken from Android iconography guidelines):
Asset Type | Prefix | Example |
---|---|---|
Icons | ic_ |
ic_star.png |
Launcher icons | ic_launcher |
ic_launcher_calendar.png |
Menu icons and Action Bar icons | ic_menu |
ic_menu_archive.png |
Status bar icons | ic_stat_notify |
ic_stat_notify_msg.png |
Tab icons | ic_tab |
ic_tab_recent.png |
Dialog icons | ic_dialog |
ic_dialog_info.png |
Naming conventions for selector states:
State | Suffix | Example |
---|---|---|
Normal | _normal |
btn_order_normal.9.png |
Pressed | _pressed |
btn_order_pressed.9.png |
Focused | _focused |
btn_order_focused.9.png |
Disabled | _disabled |
btn_order_disabled.9.png |
Selected | _selected |
btn_order_selected.9.png |
不同分辨率的图片放到不同的文件夹中,不要加-24dp等类似后缀:
图片 | 文件夹 |
---|---|
mdpi | drawable-mdpi |
hdpi | drawable-hdpi |
xhdpi | drawable-xhdpi |
xxhdpi | drawable-xxhdpi |
xxxhdpi | drawable-xxxhdpi |
Layout files should match the name of the Android components that they are intended for but moving the top level component name to the beginning. For example, if we are creating a layout for the SignInActivity
, the name of the layout file should be activity_sign_in.xml
.
Component | Class Name | Layout Name |
---|---|---|
Activity | UserProfileActivity |
activity_user_profile.xml |
Fragment | SignUpFragment |
fragment_sign_up.xml |
Dialog | ChangePasswordDialog |
dialog_change_password.xml |
AdapterView item | --- | item_person.xml |
Partial layout | --- | partial_stats_bar.xml |
A slightly different case is when we are creating a layout that is going to be inflated by an Adapter
, e.g to populate a ListView
. In this case, the name of the layout should start with item_
.
Note that there are cases where these rules will not be possible to apply. For example, when creating layout files that are intended to be part of other layouts. In this case you should use the prefix partial_
.
Similar to layout files, menu files should match the name of the component. For example, if we are defining a menu file that is going to be used in the UserActivity
, then the name of the file should be activity_user.xml
A good practice is to not include the word menu
as part of the name because these files are already located in the menu
directory.
Resource files in the values folder should be plural, e.g. strings.xml
, styles.xml
, colors.xml
, dimens.xml
, attrs.xml
Resource IDs and names are written in lowercase_underscore.
IDs should be prefixed with the name of the element in lowercase underscore. For example:
Element | Prefix |
---|---|
TextView |
tv_ |
ImageView |
iv_ |
Button |
btn_ |
Menu |
menu_ |
Image view example:
<ImageView
android:id="@+id/iv_profile"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
Menu example:
<menu>
<item
android:id="@+id/menu_done"
android:title="Done" />
</menu>
String names start with a prefix that identifies the section they belong to. For example registration_email_hint
or registration_name_hint
. If a string doesn't belong to any section, then you should follow the rules below:
Prefix | Description |
---|---|
error_ |
An error message |
msg_ |
A regular information message |
title_ |
A title, i.e. a dialog title |
action_ |
An action such as "Save" or "Create" |
Unless the rest of resources, style names are written in UpperCamelCase.
Naming. Follow the convention of prefixing the type, as in type_foo_bar.xml
. Examples: fragment_contact_details.xml
, view_primary_button.xml
, activity_main.xml
.
Organizing layout XMLs. If you're unsure how to format a layout XML, the following convention may help.
- One attribute per line, indented by 4 spaces
android:id
as the first attribute alwaysandroid:layout_****
attributes at the topstyle
attribute at the bottom- Tag closer
/>
on its own line, to facilitate ordering and adding attributes. - Rather than hard coding
android:text
, consider using Designtime attributes available for Android Studio.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="@string/name"
style="@style/FancyText" />
<include layout="@layout/reusable_part" />
</LinearLayout>
As a rule of thumb, attributes android:layout_****
should be defined in the layout XML, while other attributes android:****
should stay in a style XML. This rule has exceptions, but in general works fine. The idea is to keep only layout (positioning, margin, sizing) and content attributes in the layout files, while keeping all appearance details (colors, padding, font) in styles files.
The exceptions are:
android:id
should obviously be in the layout filesandroid:orientation
for aLinearLayout
normally makes more sense in layout filesandroid:text
should be in layout files because it defines content- Sometimes it will make sense to make a generic style defining
android:layout_width
andandroid:layout_height
but by default these should appear in the layout files
Use styles. Almost every project needs to properly use styles, because it is very common to have a repeated appearance for a view. At least you should have a common style for most text content in the application, for example:
<style name="ContentText">
<item name="android:textSize">@dimen/font_normal</item>
<item name="android:textColor">@color/basic_black</item>
</style>
Applied to TextViews:
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/price"
style="@style/ContentText"
/>
You probably will need to do the same for buttons, but don't stop there yet. Go beyond and move a group of related and repeated android:****
attributes to a common style.
Split a large style file into other files. You don't need to have a single styles.xml
file. Android SDK supports other files out of the box, there is nothing magical about the name styles
, what matters are the XML tags <style>
inside the file. Hence you can have files styles.xml
, styles_home.xml
, styles_item_details.xml
, styles_forms.xml
. Unlike resource directory names which carry some meaning for the build system, filenames in res/values
can be arbitrary.
colors.xml
is a color palette. There should be nothing else in your colors.xml
than just a mapping from a color name to an RGBA value. Do not use it to define RGBA values for different types of buttons.
Don't do this:
<resources>
<color name="button_foreground">#FFFFFF</color>
<color name="button_background">#2A91BD</color>
<color name="comment_background_inactive">#5F5F5F</color>
<color name="comment_background_active">#939393</color>
<color name="comment_foreground">#FFFFFF</color>
<color name="comment_foreground_important">#FF9D2F</color>
...
<color name="comment_shadow">#323232</color>
You can easily start repeating RGBA values in this format, and that makes it complicated to change a basic color if needed. Also, those definitions are related to some context, like "button" or "comment", and should live in a button style, not in colors.xml
.
Instead, do this:
<resources>
<!-- grayscale -->
<color name="white" >#FFFFFF</color>
<color name="gray_light">#DBDBDB</color>
<color name="gray" >#939393</color>
<color name="gray_dark" >#5F5F5F</color>
<color name="black" >#323232</color>
<!-- basic colors -->
<color name="green">#27D34D</color>
<color name="blue">#2A91BD</color>
<color name="orange">#FF9D2F</color>
<color name="red">#FF432F</color>
</resources>
Ask for this palette from the designer of the application. The names do not need to be color names as "green", "blue", etc. Names such as "brand_primary", "brand_secondary", "brand_negative" are totally acceptable as well. Formatting colors as such will make it easy to change or refactor colors, and also will make it explicit how many different colors are being used. Normally for a aesthetic UI, it is important to reduce the variety of colors being used.
Treat dimens.xml like colors.xml. You should also define a "palette" of typical spacing and font sizes, for basically the same purposes as for colors. A good example of a dimens file:
<resources>
<!-- font sizes -->
<dimen name="font_larger">22sp</dimen>
<dimen name="font_large">18sp</dimen>
<dimen name="font_normal">15sp</dimen>
<dimen name="font_small">12sp</dimen>
<!-- typical spacing between two views -->
<dimen name="spacing_huge">40dp</dimen>
<dimen name="spacing_large">24dp</dimen>
<dimen name="spacing_normal">14dp</dimen>
<dimen name="spacing_small">10dp</dimen>
<dimen name="spacing_tiny">4dp</dimen>
<!-- typical sizes of views -->
<dimen name="button_height_tall">60dp</dimen>
<dimen name="button_height_normal">40dp</dimen>
<dimen name="button_height_short">32dp</dimen>
</resources>
You should use the spacing_****
dimensions for layouting, in margins and paddings, instead of hard-coded values, much like strings are normally treated. This will give a consistent look-and-feel, while making it easier to organize and change styles and layouts.
strings.xml
Name your strings with keys that resemble namespaces, and don't be afraid of repeating a value for two or more keys. Languages are complex, so namespaces are necessary to bring context and break ambiguity.
Bad
<string name="network_error">Network error</string>
<string name="call_failed">Call failed</string>
<string name="map_failed">Map loading failed</string>
Good
<string name="error_message_network">Network error</string>
<string name="error_message_call">Call failed</string>
<string name="error_message_map">Map loading failed</string>
Don't write string values in all uppercase. Stick to normal text conventions (e.g., capitalize first character). If you need to display the string in all caps, then do that using for instance the attribute textAllCaps
on a TextView.
Bad
<string name="error_message_call">CALL FAILED</string>
Good
<string name="error_message_call">Call failed</string>
Avoid a deep hierarchy of views. Sometimes you might be tempted to just add yet another LinearLayout, to be able to accomplish an arrangement of views. This kind of situation may occur:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<RelativeLayout
...
>
<LinearLayout
...
>
<LinearLayout
...
>
<LinearLayout
...
>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</RelativeLayout>
</LinearLayout>
Even if you don't witness this explicitly in a layout file, it might end up happening if you are inflating (in Java) views into other views.
A couple of problems may occur. You might experience performance problems, because there is a complex UI tree that the processor needs to handle. Another more serious issue is a possibility of StackOverflowError.
Therefore, try to keep your views hierarchy as flat as possible: learn how to use RelativeLayout, how to optimize your layouts and to use the <merge>
tag.
Beware of problems related to WebViews. When you must display a web page, for instance for a news article, avoid doing client-side processing to clean the HTML, rather ask for a "pure" HTML from the backend programmers. WebViews can also leak memory when they keep a reference to their Activity, instead of being bound to the ApplicationContext. Avoid using a WebView for simple texts or buttons, prefer TextViews or Buttons.
If you are using an IDE such as Android Studio, you don't have to worry about this because your IDE is already obeying these rules. If not, have a look below.
The ordering of import statements is:
- Android imports
- Imports from third parties (com, junit, net, org)
- java and javax
- Same project imports
To exactly match the IDE settings, the imports should be:
- Alphabetically ordered within each grouping, with capital letters before lower case letters (e.g. Z before a).
- There should be a blank line between each major grouping (android, com, junit, net, org, java, javax).
There is no single correct solution for this but using a logical and consistent order will improve code learnability and readability. It is recommendable to use the following order:
- Constants
- Fields
- Constructors
- Override methods and callbacks (public or private)
- Public methods
- Private methods
- Inner classes or interfaces
Example:
public class MainActivity extends Activity {
private static final String CONSTANT_VALUE = "value";
private String mTitle;
private TextView mTextViewTitle;
@Override
public void onCreate() {
...
}
public void setTitle(String title) {
mTitle = title;
}
private void setUpView() {
...
}
static class AnInnerClass {
}
}
If your class is extending an Android component such as an Activity or a Fragment, it is a good practice to order the override methods so that they match the component's lifecycle. For example, if you have an Activity that implements onCreate()
, onDestroy()
, onPause()
and onResume()
, then the correct order is:
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() {}
}
Every file should have a copyright statement at the top, followed by package and import statements (each block separated by a blank line) and finally the class or interface declaration. In the Javadoc comments, describe what the class or interface does.
/*
* Copyright (C) 2015 The Android Open Source Project
*
* 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.
*/
package com.android.internal.foo;
import android.os.Blah;
import android.view.Yada;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* Does X and Y and provides an abstraction for Z.
*/
public class Foo {
...
}
Every class and nontrivial public method you write must contain a Javadoc comment with at least one sentence describing what the class or method does. This sentence should start with a third person descriptive verb.
Examples:
/** Returns the correctly rounded positive square root of a double value. */
static double sqrt(double a) {
...
}
or
/**
* Constructs a new String by converting the specified array of
* bytes using the platform's default character encoding.
*/
public String(byte[] bytes) {
...
}
You do not need to write Javadoc for trivial get and set methods such as setFoo() if all your Javadoc would say is "sets Foo". If the method does something more complex (such as enforcing a constraint or has an important side effect), then you must document it. If it's not obvious what the property "Foo" means, you should document it.
Every method you write, public or otherwise, would benefit from Javadoc. Public methods are part of an API and therefore require Javadoc. Android does not currently enforce a specific style for writing Javadoc comments, but you should follow the instructions How to Write Doc Comments for the Javadoc Tool.
According to the Android code style guide, the standard practices for some of the predefined annotations in Java are:
-
@Deprecated
: The @Deprecated annotation must be used whenever the use of the annotated element is discouraged. If you use the @Deprecated annotation, you must also have a @deprecated Javadoc tag and it should name an alternate implementation. In addition, remember that a @Deprecated method is still supposed to work. If you see old code that has a @deprecated Javadoc tag, please add the @Deprecated annotation. -
@Override
: The @Override annotation must be used whenever a method overrides the declaration or implementation from a super-class. For example, if you use the @inheritdocs Javadoc tag, and derive from a class (not an interface), you must also annotate that the method @Overrides the parent class's method. -
@SuppressWarnings
: The @SuppressWarnings annotation should only be used under circumstances where it is impossible to eliminate a warning. If a warning passes this "impossible to eliminate" test, the @SuppressWarnings annotation must be used, so as to ensure that all warnings reflect actual problems in the code.
Classes, Methods and Constructors
When annotations are applied to a class, method, or constructor, they are listed after the documentation block and should appear as one annotation per line .
/* This is the documentation block about the class */
@AnnotationA
@AnnotationB
public class MyAnnotatedClass { }
@Override
public int hashCode() { ... }
Fields
@Nullable
@Mock
DataManager mDataManager;
Use TODO comments for code that is temporary, a short-term solution, or good-enough but not perfect. TODOs should include the string TODO in all caps, followed by a colon:
// TODO: Remove this code after the UrlTable2 has been checked in.
and
// TODO: Change this to use a flag instead of a constant.
If your TODO is of the form "At a future date do something" make sure that you either include a very specific date ("Fix by November 2005") or a very specific event ("Remove this code after all production mixers understand protocol V7.").
1.We use four (4) space indents for blocks and never tabs. When in doubt, be consistent with the surrounding code. For example:
class MyClass {
int func() {
if (something) {
// ...
} else if (somethingElse) {
// ...
} else {
// ...
}
}
}
Terminology Note: When code that might otherwise legally occupy a single line is divided into multiple lines, this activity is called line-wrapping.
Note: While the typical reason for line-wrapping is to avoid overflowing the column limit, even code that would in fact fit within the column limit may be line-wrapped at the author's discretion.
We use eight (8) space indents for line wraps, including function calls and assignments. For example:
Instrument i =
someLongExpression(that, wouldNotFit, on, one, line);
Each line of text in your code should be at most 100 characters long. While much discussion has surrounded this rule, the decision remains that 100 characters is the maximum with the following exceptions:
- If a comment line contains an example command or a literal URL longer than 100 characters, that line may be longer than 100 characters for ease of cut and paste.
- Import lines can go over the limit because humans rarely see them (this also simplifies tool writing).
- One statement per line.
- Each statement is followed by a line break.
https://source.android.com/source/code-style.html
https://google.github.io/styleguide/javaguide.html#s5.2.2-class-names
https://github.com/ribot/android-guidelines/blob/master/project_and_code_guidelines.md
https://github.com/futurice/android-best-practices
Java doc: http://www.oracle.com/technetwork/java/codeconventions-150003.pdf