SignInActivity, SignInFragment, ImageUploaderService, ChangePasswordDialog。| Asset Type | Prefix | Example |
|---|---|---|
| Action bar | ab_ | ab_stacked.9.png |
| Button | btn_ | btn_send_pressed.9.png |
| Dialog | dialog_ | dialog_top.9.png |
| Divider | divider_ | divider_horizontal.9.png |
| Icon | ic_ | ic_star.png |
| Menu | menu_ | menu_submenu_bg.9.png |
| Notification | notifi_ | notifi_bg.9.png |
| Tabs | tab_ | tab_pressed.9.png |
| 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 |
| 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 |
SignInActivity,创建布局文件,那布局文件的名称就应该为 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 |
item_partial_UserActivity 创建 menu 文件时,那 menu 文件的名称就应该是 activity_user.xmlmenu 作为名称的一部分,因为这些文件已经存放在 menu 的文件下了。values 文件夹中的资源文件在命名时应该为复数。例如, strings.xml, styles.xml, colors.xml, dimens.xml, attrs.xml| 1 2 3 4 5 | void setServerPort(String value) { try { serverPort = Integer.parseInt(value); } catch (NumberFormatException e) { } } |
| 1 2 3 4 5 6 7 8 | 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! } |
close() 方法(或者类似的)然后准确的说明一下什么时候该方法会被调用到.import foo.*;import foo.Bar;ALL_CAPS_WITH_UNDERSCORES.| 1 2 3 4 5 6 7 8 | 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; } |
| Good | Bad |
|---|---|
XmlHttpRequest | XMLHTTPRequest |
getCustomerId | getCustomerID |
String url | String URL |
long id | long ID |
| 1 2 3 | if (x == 1) { x++; } |
| 1 2 | Instrument i = someLongExpression(that, wouldNotFit, on, one, line); |
| 1 2 3 4 5 6 7 8 9 10 11 | class MyClass { int func() { if (something) { // ... } else if (somethingElse) { // ... } else { // ... } } } |
| 1 | if (condition) body(); |
| 1 2 | if (condition) body();// bad! |
@Override: 该注解必须用与任何时候想要重写或者实现父类的某个方法的时候. 例如,当你使用了 @inheritdocs 标签,并且是源于一个类而并不是接口的时候,你必须同时也在此方法上加上 @Override 标签.@SuppressWarnings: 该标签只有在遇到无法忽略的警告的条件下才可以使用. 如果一个警告符合”无法忽略掉”的条件时,该标签是必须需要被使用的,为的是保证所有的警告都能反映出代码中实际存在的问题.| 1 2 3 4 | /* This is the documentation block about the class */ @AnnotationA @AnnotationB public class MyAnnotatedClass { } |
| 1 | @Nullable @Mock DataManager mDataManager; |
LogUtil 类来取代 Android 原生的 Log 类来打印日志.| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | public class Child extends Parent { private static final int CONSTANT = 1; private String mName; private int mAge; public Child(String name, int age) { mName = name; mAge = age; } @Override public void changeName() { ... } public void setName(String name) { mName = name; } private void setSomething() { ... } static class AnInnerClass { } } |
onCreate(), onDestroy(), onPause() 和 onResume(),则正确的顺序为:| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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() {} } |
Context 是非常常见的.如果遇到这种情况,那么必须将Context作为第一个参数.| 1 2 3 4 5 | // Context always goes first public User loadUser(Context context, int userId); // Callbacks always go last public void loadUserAsync(Context context, int userId, UserCallback callback); |
SharedPreferences, Bundle 和 Intent.即使在写一个很小的 app 应用时,也会产生很多字符串常量.static final,并且它们的前缀应该遵循以下的命名规则:| Element | Field Name Prefix |
|---|---|
| SharedPreferences | PREF_ |
| Bundle | BUNDLE_ |
| Fragment Arguments | ARGUMENT_ |
| Intent Extra | EXTRA_ |
| Intent Action | ACTION_ |
Fragment.getArguments() 返回的也是一个 Bundle,但是为了用于区分,所以使用 ARGUMENT_ 作为其前缀.| 1 2 3 4 5 6 7 8 | // 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"; |
Intent 或 Bundle 传递给 Fragment 和 Activity的时候, Key 的命名必须要遵循以上的命名规范.Activity 或 Fragment 需要接受参数的时候, 需要创建一个 public static 的方法来创建与之相关的 Intent 或 Fragment.getStartIntent():| 1 2 3 4 5 | public static Intent getStartIntent(Context context, User user) { Intent intent = new Intent(context, ThisActivity.class); intent.putParcelableExtra(EXTRA_USER, user); return intent; } |
newInstance(),通过传入的参数来创建 Fragment| 1 2 3 4 5 6 7 | public static UserFragment newInstance(User user) { UserFragment fragment = new UserFragment; Bundle args = new Bundle(); args.putParcelable(ARGUMENT_USER, user); fragment.setArguments(args) return fragment; } |
onCreate() 方法之前Key 应该是 private, 因为不需要类之外来使用.局部变量或方法(推荐)package 和 import 的声明| 1 2 | int longName = anotherVeryLongVariable + anEvenLongerOne - thisRidiculousLongOne + theFinalOne; |
= 运算符,换行应该在等号运算符之后,例如:| 1 2 | int longName = anotherVeryLongVariable + anEvenLongerOne - thisRidiculousLongOne + theFinalOne; |
. 之前.| 1 | Picasso.with(context).load("http://ribot.co.uk/images/sexyjoe.jpg").into(imageView); |
| 1 2 3 | Picasso.with(context) .load("http://ribot.co.uk/images/sexyjoe.jpg") .into(imageView); |
, 后进行换行.| 1 | loadPicture(context, "http://ribot.co.uk/images/sexyjoe.jpg", mImageViewProfilePicture, clickListener, "Title of the picture"); |
| 1 2 3 4 5 6 7 | loadPicture( context, "http://ribot.co.uk/images/sexyjoe.jpg", mImageViewProfilePicture, clickListener, "Title of the picture" ); |
. 之前.| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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; } }); } |
| 1 2 3 4 | <TextView android:id="@+id/text_view_profile" android:layout_width="wrap_content" android:layout_height="wrap_content" /> |
| 1 2 3 4 5 6 | <!-- Don"t do this! --> <TextView android:id="@+id/text_view_profile" android:layout_width="wrap_content" android:layout_height="wrap_content" > </TextView> |
| Element | Prefix |
|---|---|
TextView | text_ |
ImageView | image_ |
Button | button_ |
Menu | menu_ |
| 1 2 3 4 | <ImageView android:id="@+id/image_profile" android:layout_width="wrap_content" android:layout_height="wrap_content" /> |
| 1 2 3 4 5 | <menu> <item android:id="@+id/menu_done" android:title="Done" /> </menu> |
registration_email_hint 或 registration_name_hint.如果一个字符串不属于任何的领域,那应该遵循以下规则:| 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” |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | static class Foo { int mSplat; } Foo[] mArray = ... // 最慢,消耗最多 public void zero() { int sum = 0; for (int i = 0; i < mArray.length; ++i) { sum += mArray[i].mSplat; } } public void one() { int sum = 0; Foo[] localArray = mArray; int len = localArray.length; for (int i = 0; i < len; ++i) { sum += localArray[i].mSplat; } } // 推荐 public void two() { int sum = 0; for (Foo a : mArray) { sum += a.mSplat; } } |
zero() 是最慢的方法,因为 JIT 还不能对当数组进行遍历时每次都要去获得数组的长度进行优化.one() 更快一点, 因为它所有的数据都拿出来存放在局部变量里,避免了查找.只有提供了数组的长度对性能有了一定的提升two() 在没有 JIT 的设备里是最快的,但在有 JIT 的设备里于one()难分上下.它使用了 Java 1.5 版本中的增强版语法