您现在的位置:首页 >机甲狂神 >正文

「译」Android最佳实践指南——GitHub Star 70

时间2019-01-14 来源:末日进化网

  核心提示:阳春三月,夭夭碧枝,皎皎风荷,暖风熏醉,染了春扉。安静的午后,静静的梳理着自己的思绪,轻轻的敲打着心语,不想惊扰沉睡的记忆,不想扯住渐行渐远的思绪。初春的日头,终究是有了暖意的了,鹅黄的嫩绿轻轻浅浅的...
 

Updated on 2016/2/14 更新Stetho 相关,简书markdown不支持锚 -_-||||||||||||
Updated on 2016/1/15 表明谷歌对ADT的废弃态度,新增段落:对于非发布版本的构建使用不同的包名
不定时同步更新
欢迎转载,但请保留译注者链接:

Lessons learned from Android developers in . Avoid reinventing the wheel by following these guidelines. If you are interested in iOS or Windows Phone development, be sure to check also our and documents.

将 放在你的home目录或是其他应用无关的位置。某些IDE安装的时候就包含了SDK,并且会将其放置在与IDE相同的目录下。当你需要升级(或重装,或改变)IDE时这就成了一件坏事。同时还要避免将SDK放在另一个系统级别的目录下,那样很可能会让你在使用user权限运行IDE时需要用到sudo权限。

你的默认选择应该是 。Ant的限制要多并且语句还更冗长。使用Gradle,能够简单做到:

Android's Gradle plugin同时在被Google做为新标准构建系统积极开发中

有两种广泛使用的选择:旧式的Ant & Eclipse ADT project structure,和新式的Gradle & Android Studio project structure。你应该选择新式,如果你还在使用旧式,考虑将之做为宝贵遗产并转向新式吧。

Old structure:

New structure:

主要不同点在于新式使用了来自Gradle的概念,更清晰地分开了'source sets' (main, androidTest)。举个例子,你可以添加source sets 'paid' 和 'free' 到 src中作为构建 paid 版本 和 free 版本的代码目录。
使用一个top-level app对于将你的app从那些需要引用的 库项目 (e.g., library-foobar) 中区分开来很有效。settings.gradle中写着那些 能被app/build.gradle引用的 库项目 的引用。

General structure. Follow

Small tasks. 与这些 (shell, Python, Perl, etc) 脚本不同,你能用Gradle来安排tasks。Just follow for more details.

Passwords.
在app的 build.gradle中你需要为release版本的构建定义signingConfigs,以下为需要避免的事项:

不要这样做。这些信息会出现在版本控制系统中。

与之对应,通过一个不会包含在版本控制系统中的gradle.properties这样做:

这个文件将会被gradle自动载入,所以你能在build.gradle中像这样来使用它:

**使用 Maven 解决依赖而非导入 jar **
如果你明确地在项目中包含特定版本的 jar(比如说 2.1.1),下载与处理 jars 的更新将会是一件笨重累赘的事,这个问题在 Maven 中被解决得很好,这也是 Android Gradle builds 所鼓励的方式。看下面这个例子:

避免 Maven 的动态依赖
避免使用动态依赖的库版本, 像是 2.1.+ ,因为这可能会导致不同的、不稳定的构建,或是在数次构建之间表现出细微的、不可追踪的差异行为。使用静态版本像是2.1.1会创建更稳定的、可预期的和可重复的开发环境。

对于非发布版本的构建使用不同的包名
debug使用applicationIdSuffix ,这能够让debug还有release版本的apk同时安装在同一部设备上(如果你有任何需要的话,还能将此技巧应用于自定义的 build 类型)。对于一个 app 的生命周期来说,当它被发布到市场之后,这一特性将变得非常有价值。

使用不同的icons来区分安装在设备上的不同构建版本app——比如说使用不同的色彩或是使用一个覆盖的"debug"标签。对于Gradle来说,这非常容易,你只需要将debugicon 放在app/src/debug/res,而release icon 放在 app/src/release/res。你还可以针对不同的构建版本更改应用名,versionName也可以改变(就像上面这个例子做的那样)。

北京著名癫痫医院

无论使用什么编辑器,它必须能针对项目结构让人愉快地使用
文本编辑器是一个很个人的选择,依据项目结构和构建系统来让编辑器起到作用同时也是你的责任。

目前最推荐的IDE是 ,因为它由Google开发,与Gradle关系最紧密,默认使用新式项目结构,针对Android开发量身定做。

使用 来进行Android开发不再是一个好的选择。2015年,谷歌终止了对ADT的支持,并催促开发者尽快向Android Studio迁徙。and urges users toas soon as possible.你也可以继续使用它,但是需要一番配置,因为它采用旧式项目结构与Ant构建。如果 Eclipse 的 Gradle 集成令你使用得不愉快,你的选择只有使用命令行来构建。

你也能只使用一个单纯的文本编辑器像是Vim,Sublime Text, 或 Emacs。在这种情况下,你需要在命令行环境下使用 Gradle 和 adb

无论你使用什么,总得确保使用 Gradle 和新式项目结构 来构建应用,注意不要将编辑器相关的配置文件加到版本控制系统中。比如,避免添加Ant 的 build.xml 文件。
如果你在 Ant 中更改配置, 一定不要忘记让build.gradle保持 up-to-date 和 functioning 。

还有,善待其他的开发者,不要强迫他们改变他们个性化的工具配置。

是一个用于 Object 与 JSON 间相互转换的Java库。 也是一个作为解决此问题广受欢迎的存在。然而我们发现 Jackson 表现更好,因为它提供了可选择的方式来处理 JSON : streaming, in-memory tree model, and traditional JSON-POJO data binding。所以Jackson 的体积会比 GSON 要大。取决于你的实际情况,你可能倾向于选择 GSON 以避免 65k 方法数限制。其他选项还有: and

网络,缓存和图像.
这儿有好几种经过实战检验的用于后端服务器请求的解决方案,你将使用哪一种取决于你自己将要实现的客户端。使用 或 . Volley 额外提供了 helpers 以解决 载入和缓存图像。要是你选择 Retrofit, 考虑用 来做这些, 同时用 来完成高效 HTTP 请求。Retrofit, Picasso 和 OkHttp 这三个工具由同一家公司开发,所以他们能完美地补足彼此。 .

RxJava 是一个响应式编程框架,换句话说,处理异步事件。 它是一种强大并有前途的范例,可能从可读性上讲不是那么理想因为它是如此的不同。我们推荐你在使用这个库来构筑整个应用之前抱持着足够的警惕。有一些项目通过使用 RxJava 构筑, 如果你需要帮助可以和他们之中的人交谈: Timo Tuominen, Olli Salonen, Andre Medeiros, Mark Voit, Antti Lammi, Vera Izrailit, Juha Ristolainen. 我们写了一些博文发表在这上面: , , , .

如果你从前没有运用 Rx 的经历,只需要从将它作为对 API 的回应开始即可。你也可以选择从作为简单 UI 事件处理开始,像是 search field 上的点击或者输入事件。如果你对自己的 Rx 技能足够自信并决定将它应用到整个应用构筑中,一定要针对所有不易理解的部分写Javadoc。用心记住其他不熟悉 Rx 的程序员可能会对维护项目感到无比头大。尽你的全力来帮助他们理解你的代码还有 Rx 。

是一个用来让 JDK8 之前的 Android 或是其他平台支持Lambda表达式语法的库。它用于保持你的代码紧凑并可读,特别是当你使用函数式风格编写代码比如说 RxJava 。为了使用它, 你需要安装 JDK8, 在 Android Studio 的 Project Structure dialog 设置它作为你的 SDK Location , 然后设置环境变量 JAVA8_HOMEJAVA7_HOME , 接着在项目根目录的 build.gradle 引用依赖:

并在每一个模块的 build.gradle 中添加

Android Studio 提供了对于 Java8 lambda 的代码协助支持,如果你是 lambda 的新手,只需从以下建议中开始:

注意 dex 方法数限制,避免使用过多库
Android apps 当被打包成 dex file 时, 有一个固定的引用方法数限制:65536 . 如果你超出了这一限制,就会在编译时遇见一个致命错误。出于这个理由,使用尽可能少的库,并且使用这个工具 来决定使用哪些库集合来保证低于这一限制。特别要避免使用 Guava library, 因为它包含超过 13k 方法.

针对怎样最佳地通过 Fragments 和 Activities 来组织 Android 架构尚无统一结论,这一点不论在社区还是在 Futurice 的开发者中都是一样。Square 甚至开发了一个库用来最大化地通过View来构筑应用架构 ,以此绕过对于 Fragment 的依赖,但这在社区中仍未被作为广泛推荐的方案。

出于And如何治疗腹痛性癫痫roid API的历史,你能自然地想到将Fragments作为屏幕上的UI碎片。换句话说,Fragments通常与UI相关联。Activities能被自然地想到作为控制器,从生命周期和状态管理上的重要性来说。然而,你很可能遇见角色产生变化的情况:activities可能被作为UI角色(),而fragments能被单独作为控制器 。我们推荐谨慎启航,获知尽可能多的消息然后作出决定,因为无论是选择fragments-only、activities-only还是views-only架构,都存在着其缺陷。这里对于需要小心些什么有一些建议,但你需要持保留态度吸收它们:

在Java分包架构方面,Android只能算是粗略接近MVC模型。在Android中,Fragment和Activity是实际上的控制器类。从另一方面来说,它们又明显是用户接口的部分,所以同时也是视图。

出于这一理由,无法将fragments (or activities)严格划分为控制器或是视图。让它们保持自己的fragments package更好一些。Activities能放在最高级package中只要你遵循之前部分的建议。如果你计划超过两个或三个Activities,那么再加一个 activities package。

另外,也可以像经典的MVC那样来进行分包架构,通过使用一个models package包含POJOs(这些POJOs由JSON解析器解析API responses转化生成),和一个views package包含你的自定义Views,notifications, action bar views, widgets, etc。Adapters算是一个麻烦,存在于数据和视图之间。然而,典型情况是它们会通过getView()方法输出一些视图,因此你可以把adapters subpackage将在views里面。

一些application-wide的和接近于Android系统的控制器类可以放置在一个managers package中。混杂的数据处理类,像是"DateUtils",放在utils package中。那些用于与后端交互的类则放在network package中。

总的来说,序列是从 closest-to-backend 到 closest-to-the-user:

命名 遵循类型前缀惯例,像是 type_foo_bar.xml. Examples: fragment_contact_details.xml, view_primary_button.xml, activity_main.xml.

组织 layout XMLs. 如果你不确定如何格式化 layout XML, 以下惯例会有所帮助:

作为一个经验法则,android:layout_****应该在layout XML中定义,同时其他的属性android:****应该放在style XML中。这条法则会有例外,但总体而言工作得很好。这个想法是为了仅将layout (positioning, margin, sizing)和content属性放在layout files中,而外观详情 (colors, padding, font) 放在 styles files中。

那些例外是:

使用 styles. 几乎每一个项目都需要适当地使用 style,因为对于 view 来说有着重复的外观是非常常见的事,看下面这个例子:

该 style 被用于 TextViews:

你很可能需要为buttons做一些相同的事,不要在这里停下。从宏观角度上提炼出一组相关联的、重复的android:****属性到一个公共的 style 中去。

把一个大的 style 文件分割成多个
你无须拘泥于单个 styles.xml 文件。 Android SDK 支持其他不符合这一命名规则的文件,关于文件名 styles什么魔法也没有,起效果的是文件中的 XML tags <style> 。因此你能拥有这样命名的style文件 styles.xml, styles_home.xml, styles_item_details.xml, styles_forms.xml。 不像 resource 目录那样命名对构建系统具有意义, res/values 目录下的文件命名完全可以随意。
注:是的,你可以在strings.xml中放color资源,ResourceManager通过映射可以找到它。

colors.xml 是一个颜色调色板 你的colors.xml中不要放其他事物,只需要映射颜色名到一个RGBA值。不要为不同类型的buttons定义RGBA值。

长沙最好治癫痫病医院

Don't do this:

你只是简单地采用重复RGBA值来格式化,但这会使得在需要改变基础颜色的时候变得操作复杂。同时,这些定义与上下文紧密关联,像是"button" or "comment",它们应该放置于一个button style 中,而非colors.xml

Instead, do this:

向应用设计者询问调色板。命名无须全都是颜色名像是"green", "blue", etc.这样的命名也是完全可以接受的:"brand_primary", "brand_secondary", "brand_negative"。像这样格式化颜色会让改变和重定义颜色变得容易,还能让人看出一共有多少种不同的颜色被使用。通常对漂亮的UI设计来说,减少所使用颜色的多样性是一件重要的事。

好好对待 dimens.xml ,正如对待 colors.xml.你也应该定义典型的间距和字号大小的“调色板”,像对于色彩的基本意图那样。一个好的 dimens 文件的例子像是这样:

像通常对待strings那样,你应该使用spacing_**** dimensions 来设置 layouting, margins 和 paddings,而不是使用硬编码值。这会带来一致的观感,同时让组织和改变styles及layouts变得简单。

strings.xml

使用类似的命名空间来命名你的strings的keys,不要害怕在两个或多个keys中重复某一个值。语言是很复杂的,所以命名空间是有必要的,它能用于提供上下文信息还有打破模糊。

Bad

Good

不要写全大写的string值。遵循一般的文本惯例(e.g., capitalize first character)。如果你需要将整句string大写显示,那么针对实例使用TextView中的这个属性 。

Bad

Good

避免深层级的 views. 有时候你只是想要再加一个LinearLayout,用于完成一些views的布置。但这种情况却可能会发生:

尽管你没有在layout文件中直接目击到这样的景象,但这最终有可能发生,如果你填充(in Java) views到其他views中。

一些问题可能会发生。你也许遇见过性能问题,因为这样会生成一棵复杂的UI树来让处理器解析。另一个更严重的问题则是可能带来栈溢出错误: .

因此,试着让你的views层级尽可能的扁平:学习如何使用, 如何优化你的布局 还有如何使用 .

清楚与 WebView 相关的问题 当你必须要显示一个web页面的时候,比如说一篇文章,避免客户端侧的对于HTML的清理处理,更好的方式是从后端程序中直接获取一段 "纯粹的" HTML 。当持有Activity的引用而非ApplicationContext时,WebView还可能导致内存泄漏 when they keep a reference to their Activity, instead of being bound to the ApplicationContext。避免用 WebView 来做一些简单的文本或按钮, 更好的选择是 TextViews 或 Buttons。

Android SDK's testing framework尚不完善,特别是有关于UI 测试。Android Gradle实现了一个命名为的测试任务,它能运行你创造的JUnit test,参考.这意味着你需要连接实机或模拟器来运行测试,参考官方测试的指南

使用 作为 unit tests, 而不要做 views tests 这是一个致力于提高开发速度的无须连接设备的测试框架,特别适用于针对models 和 view models的单元测试。然而,Robolectric对于UI tests是不完全并且错误的。在测试以下相关UI元素时会有问题:animations, dialogs, etc,而且当你“行走于黑暗中”(没法看到屏幕正被控制着操作)时,实际情况究竟怎样也是非常难以理解的。

让写 UI tests 变得简单 你可能不需要用Robotium来连接实机跑UI case,但你仍会通过它获取好处,因为它提供了许多helpers用于获取及分析views以及控制屏幕。Test cases 将看起来很简单像是这样:

如果你是专业的Android apps开发者,买一个专业版 吧。Genymotion比原生模拟器运行起来有着更高的帧速。它拥有一些工具用于调试你的应用,像是模拟网络连接质量,GPS位置等。用于连接着进行UI test它也很理想。你还能获取许多(不是全部)不同的虚拟设备,与购买许多实机相比Genymotion专业版的花费实在是十分便宜。

警告:Genymotion emulators不支持所有的Google服务像是Google Play Store and Maps.要是你想要测试三星特征的APIs,仍旧有必要拥有一台三星实机。

常作为Android项目中缩减体积、混淆代码的工具。

是否长春公立癫痫医院使用ProGuard取决于你的项目配置。通常你可以在gradle中像这样配置以在构建正式apk时使用ProGuard。

为了决定某些代码是需要保持原样还是丢弃(注:即未实际使用,不打包,这也就是为什么使用ProGuard会减少应用体积)还是混淆,你需要在代码中指出一个或多个关键点。这些关键点区分出这些典型的类:with main methods, applets, midlets, activities, etc.
Android framework使用的默认混淆配置能在这里找到:SDK_HOME/tools/proguard/proguard-android.txt,使用这个配置,再加上你自己在这里定义的项目限定的配置:my-project/app/proguard-rules.pro,将会共同构成最终的ProGuard混淆规则。

使用ProGuard经常遇见的一个问题是应用启动时闪退,错误信息则为ClassNotFoundException or NoSuchFieldException or similar,尽管运行构建命令成功 (i.e. assembleRelease) 且无警告。
这意味着以下一到两件事:

检查app/build/outputs/proguard/release/usage.txt看是否有存疑对象被移除掉了。
检查 app/build/outputs/proguard/release/mapping.txt 看是否有存疑对象被混淆了。

防止ProGuard丢弃一些需要的类或类成员,在你的ProGuard配置中加入keep options:

防止ProGuard混淆一些需要的类或类成员,添加keepnames:

Check for some examples.
Read more at for examples.

尽早地在你的项目中提供一个正式版本构建 用来检查ProGuard是否执行正确符合预期是十分重要的事。当你引用了新库的时候,记得构建一个正式 版本在实机上测试一下。不要等到你的应用要发布"1.0"版本了再来构建正式版本,你可能会遭遇一些令人不愉快的惊喜,而你没有剩下的时间去修正它们。

建议 保存好每一个你发布给你用户的正式版本的mapping.txt file 。通过持有这些文件,你才能够debug一些问题,当你的用户遇见bug并提交了一份带有混淆的stack trace.

DexGuard. 如要你需要一个 hard-core tools 来优化并混淆正式版本代码, 可以考虑 , 制作 ProGuard 的团队推出的商用软件. 它还能轻松地分割 Dex files 以解决65k方法数限制.

如果你只需持久化简单的标志位并且你的应用只在单进程环境下运行。SharedPreferences对你来说很可能已经足够了。它是不错的默认选项。

这儿有两个原因会让你不想要使用SharedPreferences:

在SharedPreferences不够满足你的需求的情况下,你应该使用作为平台标准的ContentProvider,它快速并且进程安全。

关于ContentProvider的问题则在于你在使用它之前需要写大量的样板似的代码,还有就是低质量的学习指南。如果可能的话,使用自动库来生成ContentProvider,这样会显著减少劳力。such as .

你仍然需要靠你自己来写一些解析代码用于从Sqlite列中读取出Object数据,反之亦然。你可以序列化数据对象,像是使用Gson,并且只持有结果字串。通过这种方式你会损失一些性能,但另一方面你将不需要为数据类中的每一个域都声明列。

我们通常不推荐使用对象关系映射库Object-Relation Mapping library,除非你有着不寻常的复杂数据和迫切的需要。它们趋向复杂并需要时间去学习。如果你决定使用ORM了,要是你的应用对 进程安全 process safe 有需求的话就要注意所使用的库是否支持 这一特性,许多现存的ORM解决方案令人惊讶地不支持。

,一款来自于Facebook 的Android applications debug bridge,与Chrome 开发者工具集成在一起。使用它你很轻易就能检查应用,尤其是网络通信。它还能让你简单地检查和编辑SQLite 数据库、shared preferences。但是,你应用确保Stetho 仅在debug版本中可用,release版本中不可用。

Antti Lammi, Joni Karppinen, Peter Tackage, Timo Tuominen, Vera Izrailit, Vihtori Mäntylä, Mark Voit, Andre Medeiros, Paul Houghton and other Futurice developers for sharing their knowledge on Android development.


Creative Commons Attribution 4.0 International (CC BY 4.0)

作者:不详 来源:网络
  • 爱美文网(www.aimeiwenw.com) © 2016 版权所有 All Rights Reserved.
  • 豫ICP备15019302号
  • Powered by laoy ! V4.0.6