iOS开发以半透明模糊效果方法整理

2. GPUImage

除此之外苹果官方提供的外侧,第三着为生就点图片处理的家伙。一个被Brad
Larson的兄长就做了同效仿叫做GPUImage的开源库。同样的,里面提供了好多Filter。

https://github.com/BradLarson/GPUImage

一样是举行高斯模糊,用GPUImage可以这么:

 GPUImageGaussianBlurFilter * blurFilter = [[GPUImageGaussianBlurFilter alloc] init];
 blurFilter.blurRadiusInPixels = 2.0;
 UIImage * image = [UIImage imageNamed:@"xxx"];
 UIImage *blurredImage = [blurFilter imageByFilteringImage:image];

最少看起,代码上较用Core Image的情形大概得差不多。

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.

每当iOS开发中,我们发众多增选得开半透明模糊效果,下面就是有大面积的艺术或者说工具。

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 。

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

1. Core Image

作为规划和心得方面的负责人,苹果好对图纸效果和图纸处理的支持一定是异常好之,在iOS平台及,5.0后就是涌出了Core
Image的API。Core Image的API被在CoreImage.framework库中。

于iOS和OS X平台上,Core Image都提供了汪洋底滤镜(Filter),这吗是Core
Image库中于基本的物有。按照法定文档记载,在OS
X上发出120几近栽Filter,而当iOS上吗出90大多。

下面是同样截Core Image做模糊的示范代码:

 CIContext *context = [CIContext contextWithOptions:nil];
 CIImage *image = [CIImage imageWithContentsOfURL:imageURL];
 CIFilter *filter = [CIFilter filterWithName:@"CIGaussianBlur"];
 [filter setValue:image forKey:kCIInputImageKey];
 [filter setValue:@2.0f forKey: @"inputRadius"];
 CIImage *result = [filter valueForKey:kCIOutputImageKey];
 CGImageRef outImage = [context createCGImage: result fromRect:[result extent]];
 UIImage * blurImage = [UIImage imageWithCGImage:outImage];

此处可以看来,Core
Image为了做得比灵活,Filter都是本字符串的名去创造的,比如高斯歪曲滤镜就是“CIGaussianBlur”,这里有一个列表可以参见:
https://developer.apple.com/library/ios/documentation/GraphicsImaging/Reference/CoreImageFilterReference/index.html\#//apple\_ref/doc/filter/ci/CIGaussianBlur

除去这里提到的多Filter之外,Core
Image还提供了CIDetector等相近,可以支撑人脸识别等,在OS X上Core
Image也召开了又多支持。

永不做过怪的ViewGroup层级

虽说iOS很已经支持以模糊效果指向图片等进行处理,但进一步当iOS7过后,半透明模糊效果得到充分范围大采取。包括今年新型公布的iOS8乎传了立即同样统筹,甚至在OS
X 10.10版本Yosemite中吗开始大量以半晶莹剔透模糊。

SharedPreferences

如您不过需要持久化简单的标志位并且你的采用只于单进程环境下运行。SharedPreferences对而来说挺可能就足足了。它是天经地义的默认选项项。

这时来点儿独原因会让你切莫思只要以SharedPreferences:

  • 性能: 你持有大量数码或者数额我非常复杂
  • 多进程获取数据:
    你抱有运行于独家进程遭到的机件或是远程服务,它们要一起数据

3. vImage

实际,说罢上面的Core
Image和GPUImage,很多景下虽既够用了。下面我们再次来拘禁一个,那就算是vImage。vImage也是苹果推出的仓库,在Accelerate.framework中。

Accelerate这个framework主要是因此来举行数字信号处理、图像处理有关的于量、矩阵运算的库房。我们可认为咱们的图像都是由向量或者矩阵数据做的,Accelerate里既提供了迅猛之数学运算API,自然就是会有益我们对图像做各种各样的处理。

冲vImage我们得以因图像的处理原理直接开模糊效果,或者使现有的家伙。UIImage+ImageEffects是只特别好的图像处理库,看名字吧知道是本着UIImage做的归类扩展。这个家伙为广泛地行使着。

使用Jackson来解析JSON

4. 性能和选择

既然如此已清楚了3单道好半透明模糊效果,那么我们设为此之下理应选择哪个吧?这是个问题。

  • 自网版本的支持上来拘禁,这几个都差不多,都是iOS4、iOS5尽管支持了底,对于身于iOS8时代底开发者,这点配合已经够用了。
  • Core
    Image是苹果好之图像处理库,本来就是正确,如果苹果自身以有版本做了优化处理,自然又好。主要是故起比较累,还要亮Filter的讳。
  • GPUImage来自第三着,但贯彻开放,用起来吧比较简单,在诸多情景下是由于Core
    Image的取舍。
  • 图像模糊处理是老大复杂的盘算,最终往往使扣押性。这点达看,我还倾向选择vImage。

当自己支付之iOS应用中,选择了vImage,出发点是性,这并无是说发生深准确的benchmark。但于几个调剂时之主流机型上测,包括5c、5s等,在模糊半径(blur
radius)达到10左右的当儿,配合动画,vImage的拍卖时会显著较短缺,不见面“卡顿”。

如上是自家对iOS上落实半透明模糊效果实现之整治。

参考:

  • http://boboshone.com/blog/2013/04/22/blur-effect-in-ios/
  • http://nshipster.com/gpuimage/
  • http://blog.denivip.ru/index.php/2013/01/blur-effect-in-ios-applications/?lang=en
  • http://code.tutsplus.com/tutorials/adding-blur-effects-on-ios–cms-21488

转载自:http://www.molotang.com/articles/1921.html

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.

本篇文章要是针对性以iOS上召开半晶莹剔透模糊效果的出实现做整理。

保障colors.xml简短并谨记DRY,只在中定义基础色彩

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

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

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启动后就被用户打开的讲话。

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。

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

避WebView的客户端侧处理,并掌握其恐怕引致内存泄漏

模拟器使用Genymotion

采用多个style文件避免大成一个庞然大物

行使style来避免Layout XML中的重属性

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引用的 库项目 的引用。

Data storage 数据存储

Use Stetho

Stetho,一缓慢来自于Facebook
的Android applications debug bridge,与Chrome
开发者工具并在共同。使用她而生自由就会检查采取,尤其是网通信。它还能够被您简单地检查和编辑SQLite
数据库、shared preferences。但是,你采取确保Stetho
仅在debug版本中可用,release版本中未可用。

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也足以变动(就比如面这个例子做的那样)。

老是以 ProGuard 或 DexGuard

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道数限制.

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"));

翻译推荐阅读

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

使用Fragment呈现UI

Android SDK

将 Android
SDK
放在您的home目录或是其他以无关的职务。某些IDE安装之时光便含有了SDK,并且会以那个放置于同IDE相同的目下。当你得提升(或重装,或改)IDE时立即就是改为了平起坏事。同时还要避免以SDK放在另一个系级别的目录下,那样好可能会见受您以采用user权限运行IDE时需要因此到sudo权限。

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 方法.

Using an ORM

咱俩普通不推荐使用对象关系映射库Object-Relation Mapping
library,除非你有所不寻常的繁杂数据以及亟待解决的急需。它们趋向复杂并欲时间去学。如果您决定采取ORM了,要是你的使对
进程安全 process safe 有需要的言语就如留意所用的库房是否支持
这同一特色,许多留存的ORM解决方案令人咋舌地不支持。

Emulators 模拟器

使您是正规的Android apps开发者,买一个专业版 Genymotion
emulator吧。Genymotion比原生模拟器运行起来有更强之帧速。它装有一些工具用于调试你的动,像是拟网络连接质量,GPS位置等。用于连接着开展UI
test它吧杀出彩。你还能取许多(不是周)不同之杜撰设备,与贩多实机相比Genymotion专业版的消费实在是可怜有益。

提个醒:Genymotion emulators不支持具有的Google服务如是Google Play Store
and Maps.要是公想只要测试三星特征的APIs,仍旧有必不可少有同样大三星球实机。

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

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

License

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

简短的多寡持久化使用SharedPreferences,其他的应用ContentProvider

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

Build system 构建体系

而的默认选项应该是
Gradle。Ant的限制而多又告诉句还再次没完没了。使用Gradle,能够简单得:

  • 使不同的flavours或variants来构建而的app
  • 做简单的script-like的tasks
  • 治本并下载依赖
  • 自定义keystores
  • 还有复多

Android’s Gradle plugin同时在让Google做为新规范构建系统积极开发中

运用Gradle和它推荐的门类组织

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

Summary 概要

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

应用Stetho进行利用debug


ContentProviders

以SharedPreferences不敷满足你的要求的图景下,你应该采取作为平台正式的ContentProvider,它很快并且经过安全。

有关ContentProvider的题目虽在你在动用它之前用写大量的则似的代码,还有就是是低质量的学习指南。如果可能吧,使用机关库来生成ContentProvider,这样见面明显减少劳力。such
as
Schematic.

卿仍需要依赖你协调来写一些解析代码用于打Sqlite列中读取出Object数据,反之亦然。你可以序列化数据对象,像是运用Gson,并且仅享有结果字串。通过这种措施若见面损失有性能,但另一方面你拿无欲为数据类中之各级一个域且声明列。

Activity仅用于管理Fragment