Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

完成对things-i-wish-i-knew-before-i-wrote-my-first-android-app.md的翻译 #56

Closed
wants to merge 5 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 34 additions & 37 deletions TODO/things-i-wish-i-knew-before-i-wrote-my-first-android-app.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,21 @@



我的第一个应用写的非常糟糕。事实上,它已经弱到让我把它从应用商店直接下架了来抹去在我简历上的污点。 如果在我开发它之前我对开发有Android开发有任何了解就不会做的那么糟糕了吧。


My first app was terrible. It was so terrible, in fact, that I removed it from the store and I don’t even bother listing it on my resume’ anymore. That app wouldn’t have been so terrible if I knew a few things about Android development before I wrote it.
这里是一些当你在写你的第一个Android应用的时候需要牢牢记住的东西。这些教训都是从我在我的第一个app上犯下的真实的错误。接下来我会谈及他们。在脑海中牢记这些东西有助于写一些让你能够小骄傲的应用

Here’s a list of things to keep in mind as you’re writing your first Android apps. These lessons are derived from actual mistakes that I made in the source code of my first app, mistakes that I’ll be showing below. Keeping these things in mind will help you write an app that you can be a little prouder of.
当然,即使你按照正确的Android开发者入门方向,在之后你还是会觉得第一个写的东西糟糕透了。 就像大神 @codesstandards 说的那样:

Of course, if you’re doing your job right as a student of Android development, you’ll probably hate your app later regardless. As @codestandards says,

> If the code you wrote a year ago doesn’t seem bad to you, you’re probably not learning enough.
> 如果你一年前写的代码看上去还是不错的话,说明你这一年学的不够。
>
> — Code Standards (@codestandards) [May 21, 2015](https://twitter.com/codestandards/status/601373392059518976)

If you’re an experienced Java developer, items 1, 2, and 5 probably won’t be interesting to you. Items 3 and 4, on the other hand, might show you some cool stuff you can do with Android Studio that you might not have known about, even if you’ve never been guilty of making the mistakes I demo in those items.

## 1\. Don’t have static references to Contexts
如果你是一个有经验的Java开发者, 接下来的第1,2,和5点也许你不会很感兴趣。第3和第4点应该会向你展示一些你也许不知道的却非常酷炫屌炸天的东西在你有Android Studio的情况下能做到的。 即使你从来没有在犯下我接下来会列出的错误感到过愧疚。

## 1\. 不要把静态引用放到Context上

public class MainActivity extends LocationManagingActivity implements ActionBar.OnNavigationListener,
GooglePlayServicesClient.ConnectionCallbacks,
Expand All @@ -41,15 +41,14 @@ If you’re an experienced Java developer, items 1, 2, and 5 probably won’t b
}
}

This might seem like an impossible mistake for anyone to make. Its not. I made this mistake. I’ve seen others make this mistake, and I’ve interviewed people who weren’t very quick at figuring out why this is a mistake in the first place. Don’t do this. Its a n00b move.

If MeTrackerStore keeps a reference to the Activity passed into its constructor, the Activity will never be garbage collected. (Unless the static variable is reassigned to a different Activity.) This is because mMeTrackerStore is static, and the memory for static variables is allocated when the application first starts and isn’t collected until the process in which the application is running quits.
这事儿看起来也许是二的不一般的人才会做的事情。 但是事实上- -我犯过这个错,我也见过其他人犯过这种错。 并且我和这些不能在第一时间识别出这些错误的人交流过。 绝壁不要这么做- -这是非常傻叉的行为

If you find yourself tempted to do this, there’s probably something seriously wrong with your code. Find help. Maybe looking at Google’s Udacity course on [“Android Development for Beginners”](https://www.udacity.com/course/android-development-for-beginners--ud837) will help you out.
如果把这个Activity传递到它的构造函数里,MeTrackerStore就会持有这个Activity的引用,那么这个Activity将永远不会被垃圾回收机制回收(除非这个静态变量被重新赋值给另一个Activity)。这是因为mMeTrackerStore是静态的,静态变量的内存是应用程序开始启动就分配的,而且一直不会被回收直到应用程序的进程退出。如果你发现自己尝试这么做,那么你的代码可能有一些严重的错误。寻找帮助的话,可以看看Google’s Udacity里的课程 [“Android Development for Beginners”](https://www.udacity.com/course/android-development-for-beginners--ud837)

Note: Technically, you can hold a static reference to an application Context without causing a memory leak, but I wouldn’t recommend that you do that either. 
注意:技术上来说,你可以使用一个application Context(应用程序级的上下文对象)来持有一个静态变量的引用,但是我还是不会推荐你这么做。

## 2\. Beware of “implicit references” to objects whose lifecycle you do not control
## 2\. 小心引用那些你不能控制生命周期的隐式引用

public class DefineGeofenceFragment extends Fragment {
public class GetLatAndLongAndUpdateMapCameraAsyncTask extends AsyncTask {
Expand All @@ -69,57 +68,55 @@ Note: Technically, you can hold a static reference to an application Context wit

}

There’s multiple problems with this code. I’m only going to focus on one of those problems. In Java, (non-static) inner classes have an implicit reference to the instances of the class that encloses them.

In this example, any GetLatAndLongAndUpdateMapCameraAsyncTask would have a reference to the DefineGeofenceFragment that contains it. The same thing is true for anonymous classes: they have an implicit reference to instances of the class that contains the anonymous class.
这段代码里面有大量的错误。 这么多错误里面我只讲一点, 那就是在JAVA中,(非静态)内部类对包含它的类的实例有一个隐式的引用

The GetLatAndLongAndUpdateMapCameraAsyncTask has an implicit reference to a Fragment, an object whose lifecycle we don’t control. The Android SDK is responsible for creating and destroying Fragments appropriately and if GetLatAndLongAndUpdateCameraAsyncTask can’t be garbage collected because its still executing, the DefineGeofenceFragment that it implicitly refers to will also be kept from being garbage collected.
在这个例子里面,所有GetLatAndLongAndUpdateMapCameraAsyncTask对象都有个对DefineGeofenceFragment对象的引用。匿名类也是这样:它会对包含它的类对象有个隐式的引用。

There’s a great Google IO video [that explains why this sort of thing happens](https://www.youtube.com/watch?v=_CruQY55HOk).
Android SDK负责适当地创建和销毁Fragment对象,如果GetLatAndLongAndUpdateMapCameraAsyncTask对象正在执行所以不能被回收的话,那它持有对象也无法被回收 因为它仍然存在,DefineGeofenceFagment的隐式引用会让这货不能被回收。

## 3\. Make Android Studio work for You
这里有个[Google IO](https://www.youtube.com/watch?v=_CruQY55HOk)的视频能说明这件事儿

## 3\. 让Android Studio 为你做事

public ViewPager getmViewPager() {
return mViewPager;
}

This snippet is what Android Studio generated when I used the “Generate Getter” code completion in Android Studio. The getter keeps the ‘m’ prefixed to the instance variable and uses it when generating a getter method name. This is not ideal.

(In case you’re wondering why ‘m’ is prefixed to the instance variable name in the first place: the ‘m’ is often prefixed to instance variables by convention. It stands for ‘member.’)

Regardless of whether you think prefixing ‘m’ to your instance variables is a good idea, there’s a lesson here: Android studio can help you code to whatever convention you adopt. For example, you can use the code style dialog in Android Studio to make Android Studio automatically prepend ‘m’ to your instance variable and automatically remove the ‘m’ when its generating getters, setters, and constructor params for the instance variables.
这个片段是我使用”Generate Getter”代码补全时,Android Studio为我生成的,这个getter方法对这个实例变量保持了’m’前缀。这并不理想。

[![Screen Shot 2015-07-09 at 4.16.13 PM](http://i1.wp.com/www.philosophicalhacker.com/wp-content/uploads/2015/07/Screen-Shot-2015-07-09-at-4.16.13-PM.png?resize=620%2C432)](http://i1.wp.com/www.philosophicalhacker.com/wp-content/uploads/2015/07/Screen-Shot-2015-07-09-at-4.16.13-PM.png)
(顺手满足下你的好奇心,你一定想知道为啥实例变量声明的时候要带个’m’前缀:这个’m’常常被约定作为实例变量的前缀。它代表了’member’。)

Android Studio can do a lot more than that too. [Learning shortcuts](http://www.developerphil.com/android-studio-tips-of-the-day-roundup-1/) and learning about [live templates](https://www.jetbrains.com/idea/help/live-templates.html) are good places to start.
不论你是否认为’m’作为你实例变量的前缀是一个好主意,这里有一个我学到的教训:Android Studio可以帮你按照你养成的习惯去编写代码。比如说,你可以使用Android Studio中的代码风格框去让Android Studio自动的加上’m’到你的实例变量并且当它生成getters,setters,和构造参数时自动移除’m’。

## 4\. Methods should do one thing
Android Studio甚至可以做比上面更牛叉的事情[Learning shortcuts](http://www.developerphil.com/android-studio-tips-of-the-day-roundup-1/) 以及 [live templates](https://www.jetbrains.com/idea/help/live-templates.html) 是开始学习的好地方

There’s a method in one of the classes that I wrote that’s over 100 lines long. Such methods are hard to read, modify, and reuse. Try to write methods that only do one thing. Typically, this means that you should be suspicious of methods that are over 20 lines long. Here you can recruit Android Studio to help you spot problematic methods:
## 4\. Method应该只做一件事情

我写的这里有个超过100行的方法。这样的方法很难读懂,修改和重用。试着写仅仅做一件事的Method。一般来说,这意味着你应该注意那些你写超过20行的方法。这里你可以利用Android Studio去帮助你指出有问题的方法:
[![Screen Shot 2015-07-09 at 4.25.00 PM](http://i2.wp.com/www.philosophicalhacker.com/wp-content/uploads/2015/07/Screen-Shot-2015-07-09-at-4.25.00-PM.png?resize=620%2C435)](http://i2.wp.com/www.philosophicalhacker.com/wp-content/uploads/2015/07/Screen-Shot-2015-07-09-at-4.25.00-PM.png)

## 5\. Learn from other people who are smarter and more experienced than you.
## 5\. 从那些比你聪明和有经验的大神(老司机)学习

This might sound trivial, but its a mistake that I made when I wrote my first app.
这也许听起来非常扯淡,但是这就是当我写我第一个应用到时候犯下的错误。如果你在重复其他人犯过的错误,你这是在浪费自己的时间。在我写第一个app的时候,浪费了很多时间,如果我多花一点时间去向有经验的软件开发人员学习的话,我就可以避免一些错误,从而节省时间。不要担心,每个人都在犯错。

When you’re writing an app you’re going to make mistakes. Other people have already made those mistakes. Learn from those people. You’re wasting your time if you repeat the avoidable mistakes of others. I wasted a ton of time on my first app making mistakes that I could have avoided if I just spent a little more time learning from experienced software developers.
读下[Pragmatic Programmer](http://www.amazon.com/The-Pragmatic-Programmer-Journeyman-Master/dp/020161622X). 然后再看下 [Effective Java](http://www.amazon.com/Effective-Java-Edition-Joshua-Bloch/dp/0321356683)这本书吧 这两本书可以帮你避免一些新手常犯的错误。即使在你看完这两本书之后,也请保持着新手的姿态向大神们学习。

Read [Pragmatic Programmer](http://www.amazon.com/The-Pragmatic-Programmer-Journeyman-Master/dp/020161622X). Then read [Effective Java](http://www.amazon.com/Effective-Java-Edition-Joshua-Bloch/dp/0321356683). These two books will help you avoid making common mistakes that we make as novice developers. After you done with those books, keep looking for smart people to learn from.
## 6\. 使用库

## 6\. Use Libraries
当你写一个app,你可能会遇到那堆前人已经解决了的问题。而且,大量的解决办法都是作为资源库开放的。 好好使用这些东西吧。

When you’re writing an app, you’re probably going to encounter problems that smarter and more experienced people have already solved. Moreover, a lot of these solutions are available as open source libraries. Take advantage of them.
在我的第一个app中,我写的功能已经被其他库所提供了,它们中的一些库来自于标准的java中的一部分。另一些则是像Retrofit和Picasso这样的库。如果你不确定你要应该用什么库,你能做3件事:

In my first app, I wrote code that provided functionality that’s already provided by libraries. Some of those libraries are standard java ones. Others are third-party libraries like Retrofit and Picasso. If you’re not sure what libraries you should be using you can do three things:
1.听[Google IO Fragmented podcast episode](http://fragmentedpodcast.com/episodes/9/) 在这一节里面讲了第三方的库对于开发者是多么的重要。 透露一下,差不多就是 Dagger, Retrofit, Picasso, 和 Mockito这4个库.
2.订阅[Android Weekly](http://androidweekly.net/) 在上面看看对你有用的东西
3.寻找解决类似问题的开源应用。你可能发现它们用了第三方的库(third-party library)或者用了你并没有在意的标准的java库。

1. Listen to the [Google IO Fragmented podcast episode](http://fragmentedpodcast.com/episodes/9/). In this episode the ask developers what 3rd party libraries they see as essential for Android development. Spoiler: its mostly Dagger, Retrofit, Picasso, and Mockito.
2. Subscribe [to Android Weekly](http://androidweekly.net/). They’ve got a section that contains the latest libraries that are coming out. Keep an eye out for what seems useful to you.
3. Look for open source applications that solve problems similar to the ones that you are solving with your app. You might find one that uses a third-party library that you want to use or you might find that they’ve used a standard java library that you were unaware of.

## Conclusion
## 最后说点什么

Writing good Android apps can be very difficult. Don’t make it harder on yourself by repeating the mistakes I made. If you found a mistake in what I’ve written, please let me know in the comments. (Misleading comments are worse than no comments at all.) If you think this’ll be useful for a new developer, share it. Save them some headache.
写一个好的Android应用是非常困难大。不要重复一些我犯下的错误让写程序这件事变得更难。 如果你在我的这篇博客里面发现一些错误的话,请在评论区里告诉我。(误导的评论还不如不评论)如果你觉得这篇博客对其他开发者有帮助的话,请安利它。

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you think this’ll be useful for a new developer, share it. Save them some headache.

如果你觉得这篇博客对其他开发者有帮助的话,请安利它。

如果你觉得这篇博客对菜鸟开发者有帮助的话,请分享它。减轻他们的些许痛苦。

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lihb 你的建议是正规翻译的结果。 @bobmayuze 翻译的属于俏皮的风格。

各有各的好哈