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

Sketch是不少出品经理、UI、UX设计师时下的如出一辙暂缓的计划性工具,但是自以使Sketch的进程被发觉了一个叫自家添麻烦的政,或者说其缺少了一个本身很需要之服务:在线享受计划。可能过多动Sketch的丁都见面逢类似的题材。

Updated on 2016/2/14 更新Stetho 相关,简书markdown不支持锚
-_-||||||||||||
Updated on 2016/1/15
表明谷歌对ADT的扔态度,新增段落:对于非发布版本的构建以不同之包名
兵荒马乱时同创新原文
接转载,但要保留译注者链接:http://www.jianshu.com/p/613d28a3c8a0

自家多年来发觉了一个充分好的在线分享平台,叫做摩客原型托管。它可以解决是题材之。

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

and Windows App Development Best
Practices

documents.

首先,将你的Sketch文件导出HTML,打包成zip,然后以摩客原型托管平台,上传就好了。成功后,会扭转一个网页地址,你将此网页地址发给其他同伴,就OK了。

Summary 概要

这就是说,我们怎么管Stektch文件转为HTML呢?相信广大常常采取Sketch的情人还清楚,这里要更啰嗦下:

用Gradle和它推荐的种组织

汝需要发出Sketch
Measure插件,之后于Sketch中当选一些画板,点击工具栏上之“导出规范”按钮或利用便捷键
Ctrl + Shift + E,点击导出就好了。

以密码和能屈能伸数据在gradle.properties中

至于什么错过用摩客原型托管,包括她还装有的本子管理、密码保护、邮件群发功能,你协调去看望即使懂得,也大简单,官网是https://share.mockplus.cn。

毫不自己写Http客户端,使用Volley或OkHttp

使用Jackson来解析JSON

由于65k方法数限制,避免下Guava并维持数比较少的库房引用

使用Fragment呈现UI

Activity仅用于管理Fragment

Layout XML同样为是代码,好好组织她

以style来避免Layout XML中的还属性

动多单style文件避免大成一个特大

维持colors.xml简短并谨记DRY,只当中定义基础色彩

一样保持dimens.xml DRY,仅定义一般常量

不要打了死的ViewGroup层级

避免WebView的客户端侧处理,并明白她可能导致内存泄漏

运Robolectric做单元测试,Robotium做UI测试

模拟器使用Genymotion

连日采取 ProGuard 或 DexGuard

简简单单的数量持久化使用SharedPreferences,其他的动ContentProvider

下Stetho进行动debug


Android SDK

将 Android
SDK
放在公的home目录或是其他使用无关之岗位。某些IDE安装的当儿即便富含了SDK,并且会用其放置在与IDE相同的目下。当您用提升(或重装,或转移)IDE时就就改为了一如既往桩坏事。同时还要避免用SDK放在另一个网级别之目录下,那样非常可能会见叫您于采用user权限运行IDE时需要为此到sudo权限。

Build system 构建体系

你的默认选项应该是
Gradle。Ant的限而多又告诉句还重新没完没了。使用Gradle,能够简单完成:

  • 运不同之flavours或variants来构建而的app
  • 打造简便的script-like的tasks
  • 管理并下载依赖
  • 自定义keystores
  • 再有更多

Android’s Gradle plugin同时在受Google做啊新规范构建系统积极付出被

Project structure 项目布局

出一定量栽普遍利用的选料:旧式的Ant & Eclipse ADT project
structure,和新星的Gradle & Android Studio project
structure。你应有选择新型,如果您还以采取旧式,考虑以的做吗珍贵遗产并转化时吧。

Old structure:

old-structure
├─ assets
├─ libs
├─ res
├─ src
│  └─ com/futurice/project
├─ AndroidManifest.xml
├─ build.gradle
├─ project.properties
└─ proguard-rules.pro

New structure:

new-structure
├─ library-foobar
├─ app
│  ├─ libs
│  ├─ src
│  │  ├─ androidTest
│  │  │  └─ java
│  │  │     └─ com/futurice/project
│  │  └─ main
│  │     ├─ java
│  │     │  └─ com/futurice/project
│  │     ├─ res
│  │     └─ AndroidManifest.xml
│  ├─ build.gradle
│  └─ proguard-rules.pro
├─ build.gradle
└─ settings.gradle

关键不同点在于新式使用了来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引用的 库项目 的引用。

Gradle configuration Gradle配置

General structure. Follow Google’s guide on Gradle for
Android

Small tasks. 与这些 (shell, Python, Perl, etc)
脚本不同,你会为此Gradle来配置tasks。Just follow Gradle’s
documentation
for more details.

Passwords.
在app的
build.gradle饱受而要吗release版本的构建定义signingConfigs,以下也用避免的事项:

永不这么做。这些消息会出现在版本控制系统受。

signingConfigs {
    release {
        storeFile file("myapp.keystore")
        storePassword "password123"
        keyAlias "thekey"
        keyPassword "password789"
    }
}

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

KEYSTORE_PASSWORD=password123
KEY_PASSWORD=password789

是文件拿会见于gradle自动载入,所以若会当build.gradle中像这样来采取它们:

signingConfigs {
    release {
        try {
            storeFile file("myapp.keystore")
            storePassword KEYSTORE_PASSWORD
            keyAlias "thekey"
            keyPassword KEY_PASSWORD
        }
        catch (ex) {
            throw new InvalidUserDataException("You should define KEYSTORE_PASSWORD and KEY_PASSWORD in gradle.properties.")
        }
    }
}

**动 Maven 解决因而未导入 jar **
假定你明白地当路面临含特定版本的 jar(比如说 2.1.1),下载和拍卖
jars 的创新将会晤是一律宗笨重累赘的从业,这个题目在 Maven
中叫解决得好好,这吗是 Android Gradle builds
所鼓励的主意。看下面这例子:

dependencies {
    compile 'com.squareup.okhttp:okhttp:2.2.0'
    compile 'com.squareup.okhttp:okhttp-urlconnection:2.2.0'
}

免 Maven 的动态依赖
避免使动态依赖的库版本, 像是 2.1.+
,因为这或许会见导致差之、不平静的构建,或是在数次构建中表现有微薄之、不可追踪的距离行为。使用静态版本像是2.1.1会面创造更安宁之、可预料的同而再的支付环境。

对非发布版本的构建以不同的包名
debugbuild
type使applicationIdSuffix
,这会被debug还有release本子的apk同时装于一如既往部配备及(如果你闹另要的话,还会用以此技运用被从定义的
build 类型)。对于一个 app
的生命周期来说,当它吃宣告到市场下,这等同特色将更换得深有价。

android {
    buildTypes {
        debug {
            applicationIdSuffix '.debug'
            versionNameSuffix '-DEBUG'
        }

        release {
            // ...
        }
    }
}

使不同之icons来区别安装于设备上的差构建版本app——比如说用不同之色彩或是使用一个挂的”debug”标签。对于Gradle来说,这非常容易,你不过需要拿debugicon
放在app/src/debug/res,而release icon 放在
app/src/release/res。你还可以本着不同的构建版本更改应用名叫change app
name,versionName也堪更改(就像面是例子做的那样)。

IDEs and text editors IDE和文本编辑器

管以什么编辑器,它必须能对项目结构给人快地使
文本编辑器是一个死个人的取舍,依据项目组织以及构建系统来吃编辑器起至意向又也是您的事。

手上最好推荐的IDE是 Android
Studio,因为它由Google开发,与Gradle关系最严密,默认使用最新项目布局,针对Android开发量身定做。

使用 Eclipse
ADT
来开展Android开发不再是一个吓的挑。2015年,谷歌已了对ADT的支撑,并催促开发者尽快向Android
Studio迁徙。Google ended ADT support at the end of
2015and
urges users tomigrate to Android
Studioas
soon as
possible.你也可持续运用它,但是需要一番布局,因为她以旧式项目布局及Ant构建。如果
Eclipse 的 Gradle 集成令你以得不欢,你的挑只有采取命令执行来构建。

您吧能够惟行使一个独自的文本编辑器像是Vim,Sublime Text, 或
Emacs。在这种气象下,你需要以指令行环境下利用 Gradle 和 adb

无你用什么,总得确保下 Gradle 和新星项目组织
来构建利用,注意不要用编辑器相关的部署文件加到版本控制系统受到。比如,避免添加Ant
build.xml 文件。
若果你在 Ant 中改变配置, 一定不要遗忘给build.gradle保持 up-to-date 和
functioning 。

再有,善待其他的开发者,不要逼他们改变他们个性化的家伙配置。

Libraries 库

Jackson
是一个用以 Object 与 JSON
间相互转换的Java库。Gson
也是一个看作解决此题材普遍被欢迎之是。然而我们发现 Jackson
表现更好,因为它们提供了而是挑选的方法来拍卖 JSON : streaming, in-memory
tree model, and traditional JSON-POJO data binding。所以Jackson
的体积会比 GSON 要格外。取决于你的实际上情况,你可能支持被选择 GSON 以避免
65k 方法数限制。其他选择还有:
Json-smart
and Boon
JSON

网,缓存和图像.
这时来几许种植经过实战检验的用于后端服务器请求的缓解方案,你以使用啊一样种植在你自己快要实现之客户端。使用
Volley

Retrofit.
Volley 额外提供了 helpers 以解决 载入和缓存图像。要是你挑
Retrofit, 考虑用
Picasso
来做这些, 同时用
OkHttp
来完成高效 HTTP 请求。Retrofit, Picasso 和 OkHttp
这三独器由同样家企业开,所以他们能够全面地补足彼此。 OkHttp can also
be used in connection with
Volley.

RxJava 是一个响应式编程框架,换句话说,处理异步事件。
它是同样栽强大并发出前景的范例,可能由可读性上道不是那么漂亮因为它们是这般之例外。我们推荐你在采取这库房来修建整个应用之前抱持着足够的警醒。有一部分类通过使用
RxJava 构筑, 如果你需要帮忙可以同她俩中间的人口交谈: Timo Tuominen, Olli
Salonen, Andre Medeiros, Mark Voit, Antti Lammi, Vera Izrailit, Juha
Ristolainen. 我们形容了部分博文发表在即时上头:
[1],
[2],
[3],
[4].

比方你过去从来不采取 Rx 的经验,只待从用它当作针对 API
的对开始即可。你也可择打作为简单 UI 事件处理开始,像是 search
field 上之点击或者输入事件。如果你针对好之 Rx
技能足够自信并控制拿其利用至周应用构筑中,一定要是针对有对理解的组成部分写Javadoc。用心记住其他未熟悉
Rx
的程序员可能会见针对维护项目发无比头大。尽你的鼎力来辅助她们清楚您的代码还有
Rx 。

Retrolambda
是一个为此来受 JDK8 之前的 Android
或是其他平台支撑Lambda表达式语法的仓库。它用于保障您的代码紧凑并而读,特别是当您以函数式风格编写代码比如说
RxJava 。为了用它, 你用装 JDK8, 在 Android Studio 的 Project
Structure dialog 设置它当你的 SDK Location , 然后装环境变量
JAVA8_HOMEJAVA7_HOME , 接着以列根本目录的 build.gradle 引用依赖:

dependencies {
    classpath 'me.tatarka:gradle-retrolambda:2.4.1'
}

连以各级一个模块的 build.gradle 中补充加

apply plugin: 'retrolambda'

android {
    compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
}

retrolambda {
    jdk System.getenv("JAVA8_HOME")
    oldJdk System.getenv("JAVA7_HOME")
    javaVersion JavaVersion.VERSION_1_7
}

Android Studio 提供了于 Java8 lambda 的代码协助支持,如果您是 lambda
的新手,只需要由以下建议遭到初露:

  • 另外只生一个道的接口都是 “lambda friendly”
    的,亦即会叫抽成又连贯的语法格式
  • 假设对 参数 或外 的哟用不遵循,那么就是描写一个通常的匿名内部类并吃
    Android Studio 为公用她收缩成 lambda 格式

专注 dex 方法数限制,避免以了多库
Android apps 当被由包改成 dex file 时, 有一个定点的援方法数限制:65536
[1]
[2]
[3].
如果你过了立等同限量,就见面以编译时遇见一个致命错误。出于此理由,使用尽可能少的库房,并且动用此工具
dex-method-counts
来决定以什么库集合来保证低于这等同范围。特别要避免使 Guava library,
因为它们涵盖超过 13k 方法.

Activities and Fragments

本着如何最佳地经 Fragments 和 Activities 来组织 Android
架构尚无统一结论,这无异触及不论在社区要于 Futurice
的开发者中还是如出一辙。Square
甚至开了一个库用来最大化地通过View来构筑以架构 a library for
building architectures mostly with
Views,以这绕了对
Fragment 的因,但立刻在社区被按照无让看成大推介的方案。

出于Android
API的史,你会自然地想到以Fragments作为屏幕及之UI碎片。换句话说,Fragments通常和UI相关联。Activities能给当地想到作为控制器,从生命周期和状态管理及之关键来说。然而,你特别可能遭逢见角色来变化之状况:activities可能于当UI角色(delivering
transitions between
screens),而fragments能于单独作为控制器
fragments might be used solely as
controllers。我们引进谨慎启航,获知尽可能多的消息然后作出决定,因为无论选择fragments-only、activities-only还是views-only架构,都设有着该症结。这里对要小心把什么产生有提议,但您用持有保留态度吸收她:

  • 避免大规模采用嵌套fragments nested
    fragments
    , 这可能会见发生 matryoshka
    bugs
    。 要么在起含义的当儿使用嵌套fragments (举个例子, 在一个screen-like
    的fragment中需有些 fragments 放在一个程度方向滑的 ViewPager 中)
    ,要么就算保险这是一个深思熟虑后的支配。
  • 避放尽多代码在activities中。任何动静下要可能,让她作为轻量containers,其存意义主要在于采用之生命周期循环和任何重要的Android-interfacing
    APIs。采用单fragment的activity而非是一个单独的activity,这样可拿UI代码放在fragment中。当您得改它因为重放置到一个标签布局或是一个几近fragment表格屏幕被去的时,这令她亦可为复用。避免有一个随便针对承诺fragment的activity,除非您完全清楚这样做的产物。
  • 毫不为你的使之里工作滥用Android-level
    APIs,像是重度依赖让Intent。这恐怕会见潜移默化及Android
    OS或是其他使用,制造bugs或者延缓。举个例子,如果您的应用使用Intent作为其中通信手段,可能会见招致多秒延迟——如果其当OS启动后继之被用户打开的说话。

Java packages architecture Java分包架构

在Java分包架构方面,Android只能算是粗略接近MVC模型Model-View-Controller。在Android中,Fragment和Activity是实际的操纵器类Fragment
and Activity are actually controller
classes。从一方面来说,它们又明朗是用户接口的一部分,所以又也是视图。

是因为这无异于说辞,无法以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:

com.futurice.project
├─ network
├─ models
├─ managers
├─ utils
├─ fragments
└─ views
   ├─ adapters
   ├─ actionbar
   ├─ widgets
   └─ notifications

Resources 资源

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

组织 layout XMLs. 如果你无确定哪些格式化 layout XML,
以下惯例会具有帮助:

  • 一个性能一行,4 空格缩进
  • android:id 总是作为第一个属性
  • android:layout_**** 这类似性质在最上面
  • style 属性放在最下
  • Tag closer /> 拥有好之一律行, 以要各个清晰和添加属性变得易
  • 和那利用硬编码 android:text, 不如考虑动用规划时属性 Designtime
    attributes
    ,其受 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>

作为一个涉法则,android:layout_****当于layout
XML中定义,同时另外的属性android:****应当放在style
XML中。这漫长法虽会发生两样,但总体而言工作得非常好。这个想法是为着单纯用layout
(positioning, margin, sizing)和content属性放在layout files中,而外观详情
(colors, padding, font) 放在 styles files中。

那些例外是:

  • android:id 明显应该放在 layout files 中
  • android:orientation 属性对于 LinearLayout 来说一般 放在 layout
    files 中更有意义
  • android:text 应该放在 layout files 中盖其定义了 content
  • 聊情况下为 style 来定义 android:layout_width
    android:layout_height 常量会很有因此,但默认情况下其应出现在
    layout files 中

使用 styles. 几乎每一个门类都待适宜地行使 style,因为于 view
来说有更的外观是雅大的从业,看下面是例子:

<style name="ContentText">
    <item name="android:textSize">@dimen/font_normal</item>
    <item name="android:textColor">@color/basic_black</item>
</style>

该 style 被用于 TextViews:

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/price"
    style="@style/ContentText"
    />

您大可能需要吗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:

<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>

而只是略地以重新RGBA值来格式化,但当下会叫在急需转移基础颜色之时光换得操作复杂。同时,这些概念跟上下文紧密关系,像是”button”
or “comment”,它们该放置于一个button style 中,而不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>

往利用设计者询问调色板。命名无须全都是颜色名像是”green”, “blue”,
etc.这样的命名吧是截然好承受的:”brand_primary”, “brand_secondary”,
“brand_negative”。像这么格式化颜色会给改变跟重定义颜色变得爱,还能够被人看一共有微微种不同之颜料为运用。通常对优秀的UI设计吧,减少所采取颜色的多样性是一律宗主要之行。

精对待 dimens.xml ,正如对待
colors.xml.
若呢应当定义典型的间距和字号大小的“调色板”,像于情调的着力打算那样。一个吓的
dimens 文件之例证像是这么:

<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>

比如说普通比strings那样,你该采取spacing_**** dimensions 来设置
layouting, margins 和
paddings,而不是以硬编码值。这会带来一样的观感,同时给组织与改变styles及layouts变得简单。

strings.xml

使类似之命名空间来定名你的strings的keys,不要害怕在简单个或多单keys中再次某个一个值。语言是充分复杂的,所以命名空间是出必不可少之,它亦可用来供上下文信息还有打破模糊。

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>

绝不写全好写的string值。遵循一般的文件惯例(e.g., capitalize first
character)。如果您待拿整句string大写著,那么对实例使用TextView中之这特性textAllCaps

Bad

<string name="error.message.call">CALL FAILED</string>

Good

<string name="error.message.call">Call failed</string>

免大层级的 views.
有时候你只是想只要重加一个LinearLayout,用于完成部分views的摆设。但这种场面可可能会见来:

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    >

    <RelativeLayout
        ...
        >

        <LinearLayout
            ...
            >

            <LinearLayout
                ...
                >

                <LinearLayout
                    ...
                    >
                </LinearLayout>

            </LinearLayout>

        </LinearLayout>

    </RelativeLayout>

</LinearLayout>

尽管你从未于layout文件中一直目睹到如此的场景,但马上最终有或产生,如果你填充(in
Java) views到其他views中。

片问题恐怕会见起。你可能遇见过性问题,因为这么会异常成一株复杂的UI树来让电脑解析。另一个重新重的题目虽是唯恐带来栈溢出左:
StackOverflowError.

就此,试着被您的views层级尽可能的扁平:学习怎样以RelativeLayout,
如何优化你的布局 optimize your
layouts
还有哪些采取 <merge>
tag.

明白与 WebView 相关的题材
当你必使展示一个web页面的早晚,比如说一首文章,避免客户端侧的于HTML的清理处理,更好的章程是于后端程序中一直获取一截
纯粹的” HTML
。当有Activity的援而不ApplicationContext时,WebView还可能造成内存泄漏WebViews
can also leak
memory
when they keep a reference to their Activity, instead of being bound to
the ApplicationContext。避免因此 WebView 来做一些简短的公文或按钮,
更好的挑选是 TextViews 或 Buttons。

Test frameworks 测试框架

Android SDK’s testing framework尚非圆满,特别是有关于UI 测试。Android
Gradle实现了一个命名吧connectedAndroidTest的测试任务,它会运作而创造的JUnit
test,参考extension of JUnit with helpers for
Android.这意味你需要连续实机或模拟器来运作测试,参考官方测试的指南[1]
[2]

使用 Robolectric
作为 unit tests, 而毫无开 views tests

这是一个行为加强支付进度的永不连接装置的测试框架,特别适用于对models
和 view models的单元测试。然而,Robolectric对于UI
tests是免全以错误的。在测试以下相关UI元素时会发生题目:animations,
dialogs,
etc,而且当您“行走于黑暗中”(没法看屏幕正让操纵着操作)时,实际情况究竟哪呢是可怜难知晓的。

Robotium
让写 UI tests 变得简单
你或未待为此Robotium来连接实机跑UI
case,但你本会由此她赢得利益,因为其提供了不少helpers用于取与分析views以及控制屏幕。Test
cases 将关押起非常简短像是这么:

solo.sendKey(Solo.MENU);
solo.clickOnText("More"); // searches for the first occurence of "More" and clicks on it
solo.clickOnText("Preferences");
solo.clickOnText("Edit File Extensions");
Assert.assertTrue(solo.searchText("rtf"));

Emulators 模拟器

倘你是正规的Android apps开发者,买一个标准版 Genymotion
emulator吧。Genymotion比原生模拟器运行起来有更胜之帧速。它兼具一些家伙用于调试你的运用,像是模仿网络连接质量,GPS位置等。用于连接在开展UI
test它吗充分可观。你还能够博取许多(不是整套)不同之虚拟设备,与购买多实机相比Genymotion专业版的花实在是可怜利。

警戒:Genymotion emulators不支持有的Google服务如是Google Play Store
and Maps.要是您想要测试三星球特征的APIs,仍旧有必不可少有同等台三星体实机。

Proguard configuration Proguard配置

ProGuard
常作为Android项目遭到裁减体积、混淆代码的家伙。

是不是使用ProGuard取决于你的类别安排。通常你可以当gradle中诸如这么安排为当构建标准apk时行使ProGuard。

buildTypes {
    debug {
        minifyEnabled false
    }
    release {
        signingConfig signingConfigs.release
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}

为了操纵某些代码是需要保持原样还是抛弃(注:即非实际利用,不从包,这也不怕是怎么采取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) 且无警告。
立即代表以下一到一定量宗事:

  1. ProGuard移除了看似、枚举、方法、域或注解,检查一下哪些是勿需要移除的一部分。
  2. ProGuard混淆(重命名)了仿佛、枚举、域,但这些都在代码中吃一直利用了她原来的命名,
    i.e. through Java reflection.

检查app/build/outputs/proguard/release/usage.txt看是不是发生存疑对象为移除掉了。
检查 app/build/outputs/proguard/release/mapping.txt
看是否有怀疑对象被歪曲了。

严防ProGuard丢弃一些用之好像还是看似成员,在你的ProGuard配置中参加keep
options:

-keep class com.futurice.project.MyClass { *; }

戒ProGuard混淆一些待的接近或近乎成员,添加keepnames:

-keepnames class com.futurice.project.MyClass { *; }

Check this template’s ProGuard
config
for some examples.
Read more at
Proguard
for examples.

不久地以您的品种面临提供一个正规版本构建
用来检查ProGuard是否实施是符合预期是生重点的从业。当您引用了初仓库底时,记得构建一个正规
版本在实机上测试一下。不要赶你的利用要颁布”1.0″版本了再来构建标准版本,你也许会见遭一些叫人非喜的大悲大喜,而若没剩余的时去匡正它们。

建议 保存好各级一个而发表让您用户之专业版本的mapping.txt file
。通过拥有这些文件,你才能够debug一些题目,当您的用户遇见bug并交给了同等客包含混淆的stack
trace.

DexGuard. 如要你要一个 hard-core tools 来优化并混淆正式版本代码,
可以设想
DexGuard,
制作 ProGuard 的团体推出的商用软件. 它还能自在地划分 Dex files
以化解65k主意数限制.

Data storage 数据存储

SharedPreferences

倘你不过待持久化简单的标志位并且你的利用只当单进程环境下运作。SharedPreferences对君吧十分可能已足够了。它是毋庸置疑的默认选项项。

这会儿有点儿个由会为您无思量如果使用SharedPreferences:

  • 性能: 你具备大量数目还是数本身非常复杂
  • 差不多进程获取数据:
    你有着运行在个别进程被之零件或是远程服务,它们需共同数据

ContentProviders

每当SharedPreferences不足够满足你的要求的状况下,你应当使作为平台标准的ContentProvider,它很快又经过安全。

有关ContentProvider的题目则在于你当采用其前面需要写大量的师似的代码,还有即使是低质量之学习指南。如果可能吧,使用电动库来生成ContentProvider,这样见面肯定滑坡劳力。such
as
Schematic.

君依旧需要借助你自己来形容一些解析代码用于从Sqlite列中读取出Object数据,反之亦然。你得序列化数据对象,像是利用Gson,并且独自具备结果字串。通过这种方式若见面损失有性质,但一方面你以非需呢数据类中之各级一个域还声明列。

Using an ORM

咱俩便不推荐使用对象关系映射库Object-Relation Mapping
library,除非你拥有不寻常的复杂性数据以及亟待解决的要。它们趋向复杂并欲时间去读书。如果您控制采取ORM了,要是你的运用对
进程安全 process safe 有要求的语句就是设注意所利用的堆栈是否支持
这同一特性,许多存的ORM解决方案令人惊呆地无支持。

Use Stetho

Stetho,一缓来自于Facebook
的Android applications debug bridge,与Chrome
开发者工具并在一起。使用它们你异常随意就能够检查下,尤其是网络通信。它还会给你简单地检讨及编SQLite
数据库、shared preferences。但是,你利用确保Stetho
仅以debug版本中可用,release版本中无可用。

Thanks to

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.

License

Futurice Oy
Creative Commons Attribution 4.0 International (CC BY 4.0)

翻译推荐阅读

  • dex分包
  • 「打造好之Library」SharedPreferences篇
  • 动Chrome来调节你的Android
    App

Post Author: admin

发表评论

电子邮件地址不会被公开。 必填项已用*标注