`

Android4开发入门经典 之 第十二部分:最佳实践

 
阅读更多


性能提升

有两个编写有效代码的基本规则:

1:不要做你不需要做的。
2:不分配没必要分配的内存。
 

应该尽量避免创建多余的对象,比如:

1:在一组输入数据中抽取字符串时,尝试返回源数据的子串,而非创建一个副本
2:如果你有一个返回String的方法,而且你知道它的结果将会一直被追加到StringBuffer,改变你的签名和实现,在这个函数里面直接追加,避免创建临时对象。
3:将多维数组切成与之平行的一维数组
4:一个int数组比Integer数组要好,一个公认的事实就是两个平行的int数组要比一个(int,int)对象数组要高效很多。对于其它原始数据类型亦如是

应该尽量使用Native方法 ,比如:

当处理字符串时,要毫不犹豫地使用诸如String.indexOf()、String.lastIndexOf()之类的专门方法,这些是典型的用C/C++代码实现的方法,它们可以轻易地比实现同样功能的Java循环快10-100倍

优先使用实现类,而不是接口

对于嵌入式系统来说,通过接口的引用来调用一个方法要比通过一个具体类型的引用调用virtual方法花多2倍的时间。
但是公共API除外,好的API较少考虑性能。

优先选择static而非virtual

如果你不必访问一个对象的字段,使你的方法成为static方法。它可以被更快地调用,因为它不需要一个虚拟方法来间接调用。

避免内部的Getter/Setter

在Android,虚拟方法调用代价是昂贵的,实例字段查找代价更高。沿用一般面向对象编程实践在公开接口中提供gettter和setter是合理的,但在一个类中你应该直接访问字段 。
 
访问对象字段要比访问本地变量慢得多,如下面这段: 

java代码:
for (int i = 0; i < this.mCount; i++) 
dumpItem(this.mItems[i]); 
应该写成这样: 
int count = this.mCount; 
Item[] items = this.mItems; 
for (int i = 0; i < count; i++) 
dumpItems(items[i]); 
(我们用一个显式的"this"来表明这是一个成员变量。)
同样的,不要在for语句中的第二个从句中调用方法。例如下面这段代码将会在每次迭代中都会执行一次getCount(),这是一个巨大的浪费,你可以将它的值cache为一个int。 
java代码:
for (int i = 0; i < this.getCount(); i++) 
    dumpItems(this.getItem(i)); 

缓存查询字段 , 通常,如果你将要访问一个实例字段多次,一个好的习惯就是创建一个临时变量。例如: 

java代码:
protected void drawHorizontalScrollBar(Canvas canvas, int width, int height) { 
        if (isHorizontalScrollBarEnabled()) { 
            int size = mScrollBar.getSize(false); 
            if (size <= 0) { 
                size = mScrollBarSize; 
            } 
            mScrollBar.setBounds(0, height - size, width, height); 
            mScrollBar.setParams( computeHorizontalScrollRange(), 
                    computeHorizontalScrollOffset(), 
                    computeHorizontalScrollExtent(), false); 
            mScrollBar.draw(canvas); 
        } 
    } 

这是对成员字段mScrollBar的四次分开查找,通过将mScrollBar缓存到本地变量,四次成员字段查找变成四次本地变量引用,这样更为高效。 
同样地,方法参数作为本地变量拥有相同的性能特征。

 
声明常量为static final,主要是针对属性字段,你也可以将本地变量声明为final,然而这并无真正意义上的性能提升 。
使用增强的For循环语句
增强的For语句对于数组表现良好,但对iterable对象要小心使用,因为有额外的对象创建。对于ArrayList,你最好直接遍历它,但对于其它collections,增强的For循环语句将会等同于显式的迭代用法。
避免使用Enum类型
避免使用Float类型
嵌入式处理器很少具有硬件浮点支持,所以所有的“float”和“double”操作都是在软件上进行。某些基本的浮点操作可能会花费数微秒。
避免使用JNI

支持多种屏幕

在实际开发中,由于由于不同手机的尺寸大小,屏幕分辨率可能存在差异,这会带来很多的问题,比如:

1:图片在不同的设备上,大小显示不一
2:Layout在不同的设备上,显示不一样,可能变形了

一些基本的解决方法:

1:对于字体,尽量使用sp作为单位,其他的尽量使用dp或者dip
2:使用wrap_content, fill_parent, 或者 dp 来定义layout的尺寸大小
3:不同密度设备对应图像文件的最佳比例。
对于四种密度low-dpi, medium-dpi, high-dpi, extra high-hdpi的设备,在指定一个相同的图像文件时,分配给各种密度的图像文件的尺寸应该符合以下比例:3:4:6:9. 也就是要符合密度比例(120:160:240:360)。

举个列子,假如我们要在一个密度为160dpi的设备上使用到一个48 * 48的图像文件。那么对于其它密度的设备,我们要准备的图像文件分别是:

low-density (120dpi) : 36×36
medium-density(160dpi): 48×48
high-density (240dpi) : 72×72
high-density (360dpi): 96×96 
4:在需要的情况下,为每种尺寸的设备提供指定的layout文件。
5:在需要的情况下,为每种密度的设备提供不同的图像文件
6:不使用absoluteLayout布局

UI最佳实践

这是一份来自Moto的,关于Android UI的最佳实践,要点如下:

1:阅读UI指导方针(UI guideline)
2:理解和设计触摸模式
3:支持多种交互模式 (如键盘、轨迹球、触摸屏等)
4:使用通知(notifications)和窗口阴影(window shade)
5:支持应用间的交互
6:保持你的用户界操作面快速且敏感
7:使用窗体部件和文件夹
8:运用屏幕方向的改变
9:巧用图片
10:使用适用于多设备的布局

这是一份来自Android官方开发者博客,关于Android UI的最佳实践

不应该

1.不要照搬你在其它平台的UI设计,应该让用户感觉是在真正使用一个 Android 软件,在你的商标显示和平台整体观感之间做好平衡 
2.不要过度使用模态对话框 
3.不要使用固定的绝对定位的布局 
4.不要使用px单位,使用dp或者为文本使用sp 
5. 不要使用太小的字体

应该

1. 为高分辨率的屏幕创建资源(缩小总比放大好) 
2. 需要点击的元素要够大 
3. 图标设计遵循 Android 的准则 
4. 使用适当的间距(margins, padding) 
5. 支持D-pad和trackball导航 
6. 正确管理活动(activity)堆栈 
7. 正确处理屏幕方向变化 
8. 使用主题/样式,尺寸和颜色资源来减少多余的值 
9.和视觉交互设计师合作!!! 

设计哲学

1. 干净而不过于简单 
2. 关注内容而非修饰 
3. 保存一致,让用户容易投入其中,可附加少许变化 
4. 使用云端服务(存储和同步用户资料)来加强用户体验

优秀界面的设计准则

1. 关注用户 
2. 显示正确的内容 
3. 给予用户适当的回馈 
4. 有章可循的行为模式 
5. 容忍错误

关注用户

1. 了解你的用户(年龄,技能,文化,对你的应用的需求,使用的设备,何时何地如何使用设备) 
2. ‘用户优先’的设计心态 (用户通常是任务导向的行为模式) 
3. 更早,更频繁的由真实用户来测试

显示正确的内容 

1. 最常用的操作需要最快被用户看到并且可用 
2. 不太常用的功能可以放到菜单里面
 

给予用户适当的回馈

1. 交互式的UI元素最少需要反映出4种不同的状态 (default,disabled,focused,pressed) 
2. 保证操作的结果是清晰可见的 
3. 多给予用户进度提示,但是不要干扰他们当前的操作

有章可循的行为模式

1. 行为模式遵循用户的期望(正确的操作活动堆栈,显示用户期望看到的信息和动作) 
2. 使用合适的方式来加强功能可见性(可点击的元素就应该看起来是可以点击的) 
3. 如果用户完成一项任务需要复杂的操作,重新思考你的设计!!!

容忍错误

1. 只允许有意义的操作(适当禁用一些按钮) 
2. 尽量减少不可回退的操作 
3. 允许回退(undo)比使用确定对话框更好(实际上,应该尽量少用确定对话框,它对用户是一种干扰)如果错误是可能发生的,那它就一定会发生。

设计的考量

1.屏幕的物理尺寸 
2.屏幕密度 
3. 屏幕的方向(竖向和横向) 
4.主要的UI交互方式(触屏还是使用D-pad/trackball) 
5.软键盘还是物理键盘
6.了解不同设备之间的相异之处是非常重要的! 
7.阅读CDD,学习设备可能差异的地方 
8.了解屏幕尺寸和密度分类
 

响应的灵敏性(Designing for Responsiveness)

应用程序响应不够灵敏的地方包括——反映迟钝,挂起或冻结很长时间,或者需要花费很长的时间来处理输入。
在 Android上,如果你的应用程序有一段时间响应不够灵敏,系统会向用户显示一个对话框,这个对话框称作应用程序无响应 (ANR:Application Not Responding)对话框。
什么引发了ANR:在Android里,应用程序的响应性是由Activity Manager和Window Manager系统服务监视的。当它监测到以下情况中的一个时,Android就会针对特定的应用程序显示ANR:
1:在5秒内没有响应输入的事件(例如,按键按下,屏幕触摸)
2:BroadcastReceiver在10秒内没有执行完毕

如何避免ANR

运行在主线程里的任何方法都尽可能少做事情。特别是,Activity应该在它的关键生命周期方法(如onCreate()和onResume()) 里尽可能少的去做创建操作。潜在的耗时操作,例如网络或数据库操作,或者高耗时的计算如改变位图尺寸,应该在子线程里(或者以数据库操作为例,通过异步请 求的方式)来完成。

增强响应灵敏性

一般来说,在应用程序里,100到200ms是用户能感知阻滞的时间阈值。这里有一些额外的技巧来避免ANR,并有助于让你的应用程序看起来有响应性。
1:如果你的应用程序为响应用户输入正在后台工作的话,可以显示工作的进度(ProgressBar和ProgressDialog对这种情况来说很有用)。
2:特别是游戏,在子线程里做移动的计算。
3:如果你的应用程序有一个耗时的初始化过程的话,考虑可以显示一个Splash Screen或者快速显示主画面并异步来填充这些信息。在这两种情况下,你都应该显示正在进行的进度,以免用户认为应用程序被冻结了。
简介:即使你的应用程序是快速且响应灵敏 的,但一些设计仍然会给用户造成问题——与其它应用程序或对话框未事先计划的交互,意外的数据丢失,意料之外的阻塞等等。简而言之,你应该竭尽全力去开发一个与系统和其它应用程序流畅交互的应用程序。

常见的流畅性问题:

1:一个应用程序的后台处理——例如,一个Service或者BroadcastReceiver—— 弹出一个对话框来响应一些事件。这可能看起来没啥大碍,然而,当你的应用程序运行在真机上时,有可能你的应用程序在没有获得用户焦点时后台处理显示了一个对话框。因此,可能会出现在活跃的应用程序后方显示了你的应用程序的对话框,或者从当前应用程序 夺取焦点显示了一个对话框,而不管当前用户正在做什么(例如,正在打电话)。 种情况就应该使用Notification来处理,而不是夺取焦点和打断用户。
2:另一个例子是未能正确实现Activity的onPause()和其它生命周期方法而造成意外丢失了状态或用户数据。

流畅性设计指南

1:别丢弃数据

如果用户在你的应用程序中正在编辑数据时,其它Activity出现了,这时,你的应用程序被杀死时可能丢失那些数据。
Android方式”是这样做的:能接收和编辑用户输入的Android应用程序应该重写onSaveInstanceState()方法,并以恰当的方式保存它们的状态。 对于持久性的数据应该在onPause()方法里面保存。

2:不要暴露原始数据

暴露原始数据,要求其它应用程序能够理解你的数据的格式;如果你变更了格式,那么,你将破坏那些没有进行同步更新的应用程序。
“Android方式”是创建一个ContentProvider,以一种清晰的、深思熟虑的和可维护的API方式暴露你的数据给其它应用程序。使用ContentProvider,就好像是插入Java接口来分离和组装两片高耦合的代码。这意味着你可以修改数据的内部格式,而不用修改由ContentProvider暴露的接口,这样,也不会影响其它应用程序。

3:不要打断用户

如果用户正在运行一个应用程序(例如,Phone程序),断定对用户操作的目的才是安全的。这也就是为什么必须避免创建Activity,而是直接在当前的Activity中响应用户的输入。
那就是说,不要在BroadcastReceiver或在后台运行的Service中调用callActivity()。这么做会中断当前运行的应用程序,并导致用户恼怒。也许更糟糕的是,你的Activity可能成为“按键强盗”,窃取了用户要提供给前一个Activity的输入。视乎你的应用程序所做的事情,这可能是个坏消息。
不选择在后台直接创建Activity UI,取而代之的是,应该使用NotificationManager来设置Notification。它们会出现在状态栏,并且用户可以在他空闲的时候点击它们,来查看你的应用程序向他显示了什么。
(注意,如果你的Activity已经在前台了,以上将不适用:这时,对于用户的输入,用户期望的是看到下一个Activity来响应。)

4:有太多事情要做?在线程里做

如果你的应用程序需要执行一些昂贵或耗时的计算的话,你应该尽可能地将它挪到线程里。这将阻止向用户显示可怕的“Application Not Responding”对话框。

5:不要让一个Activity超负荷

任何值得使用的应用程序都可能有几个不同的屏幕,当设计你的应用程序的时候,把你的应用程序看作是Activity对象的集合。从长远来看,这会使得你的代码更加方便维护。

6:扩展系统主题

当设计你的UI时,你应该尽量避免太多自己的主题。相反的,使用同一个主题。你可以重写或扩展你需要的主题部分,但至少在与其它应用程序相同的UI基础上开始。

7:设计你的UI可以应付多屏幕分辨率

不同的Android设备可能支持不同的屏幕分辨率,应确保你的布局和图片能足够灵活地在不同的设备屏幕上正常显示。

8:假设网络很慢

你应该按照最小化的网络访问和带宽来编写你的代码。

9:不要假定触摸屏或键盘

创建应用程序的时候,不要假定特定的键盘布局——除非你真的想限定你的应用程序只运行在某些设备上。

10:节省设备电池

如何让你的应用程序最小化的占用处理器,归根结底还是要写高效代码。为了减少无线的电量消耗,确保对错误条件进行正确的处理,并只获取你要的东西。
视频配套PPT,视频地址【 Android4开发入门经典独家视频课程
11
15
分享到:
评论
1 楼 tag13346 2012-07-24  
看来手机开发确实是门学问,和很多常识都是反的

相关推荐

    Android开发入门经典

    “第十二部分 Android开发最佳实践”部分将讨论提高Android应用性能,如何支持多种屏幕尺寸,以及UI设计的最佳实践,确保应用具有良好的响应性和流畅性。 整体来看,本文档作为一份完整的Android开发入门教程,从最...

    Android 应用开发入门经典教程

    以上只是《Android应用开发入门经典教程》中部分内容的概述,实际教程会更深入地探讨每个主题,通过实例和练习帮助读者巩固知识,真正掌握Android应用开发。如果你对Android开发感兴趣,这无疑是一份值得深入学习的...

    google android开发入门指南(第三版) 源代码

    《谷歌Android开发入门指南...通过研究《谷歌Android开发入门指南(第三版)》的源代码,开发者不仅能学习到Android开发的基本概念和技术,还能了解到实际项目中的一些最佳实践,为后续的深入学习和开发打下坚实基础。

    Google.Android开发入门与实战(第二版)源码

    "Google.Android开发入门与实战(第二版)源码"是一个极好的资源,它是由eoe社区的一群经验丰富的开发者编著而成,旨在帮助初学者和进阶者深入理解Android应用开发的核心概念和技术。这本书的第二版更新了最新的开发...

    Android开发从入门到精通源码

    《Android开发从入门到精通源码》是一份全面学习Android应用开发的重要资源,包含了扶松柏老师教学课程的源代码。这份源码分为两大部分,分别对应教程的2-6章和7-12章,旨在帮助初学者逐步掌握Android开发的核心技能...

    Android.游戏开发入门

    在《Android游戏开发入门》这本书中,作者Mario Zechner将引导读者通过十四章的内容深入理解Android平台上的游戏开发技术。本书不仅适合初学者,也适用于有一定编程基础但希望在Android平台上进行游戏开发的程序员。...

    android开发入门资料

    《Android开发入门资料详解》 Android开发作为移动应用开发的重要领域,吸引着众多开发者投身其中。这份"android开发入门资料"旨在为初学者提供全面、深入的指导,帮助他们快速理解Android开发的基础知识和实践技巧...

    Beginning Android Games( Android 游戏开发入门)

    ### Android游戏开发入门知识点概述 #### 一、书籍基本信息及适用人群 - **书籍名称**:《Beginning Android Games》(Android游戏开发入门) - **作者**:Mario Zechner - **出版信息**:Apress出版社,2011年4月...

    Android 4 游戏开发入门(Beginning Android 4 Games Development)

    ### Android 4 游戏开发入门关键知识点概览 #### 一、图书基本信息与目标读者 - **出版日期**:2011年12月15日。 - **作者**:Mario Zechner 和 Robert Green。 - **目标读者**: - 对Android平台有一定Java基础...

    Android开发入门案例+源代码适合新人

    "Android开发入门案例+源代码"是一个非常适合新人的学习资源,它提供了丰富的实践案例,帮助新手快速理解和掌握Android应用开发的基本概念和技术。这本书的第四版可能包含了一些最新的API和最佳实践,确保了学习内容...

    android开发入门教程

    Android开发入门教程旨在帮助初学者快速掌握Android应用开发的基本技能,构建自己的第一个应用程序。这个教程将涵盖以下几个核心知识点: 1. **环境配置**:首先,你需要安装Java Development Kit (JDK) 和Android ...

    google android开发入门指南(第三版)(1)英文原版

    ### Google Android 开发入门指南(第三版)知识点总结 #### 一、书籍概述与目标读者 - **书籍名称**:Google Android 开发入门指南(第三版) - **目标读者**:本书面向Android初学者,旨在帮助他们从零基础快速...

    Android从入门到精通 的 课后练习项目源码 巅峰卓越 编著 中国工信出版社 人民邮电出版社 责任编辑 张翼 我的第1本Android开发书

    《Android从入门到精通》是一本为初学者量身打造的Android开发教程,由巅峰卓越编著,并由中国工信出版社和人民邮电出版社联合出版。这本书深入浅出地讲解了Android开发的基本概念和技术,旨在帮助读者从零基础快速...

    Android网络开发从入门到精通源码—代林峰

    十、最佳实践与优化 最后,了解网络请求的最佳实践,如合理的缓存策略、减少不必要的请求、使用GZIP压缩等,能进一步提升应用性能和用户体验。 通过学习和实践上述知识点,开发者不仅可以理解Android网络编程的基本...

    Android移动应用开发从入门到精通[有明细目录PDF+源代码 全

    这本书分为20个章节,旨在帮助初学者系统地学习并掌握Android开发技能,同时也适合有一定基础的开发者进行深入研究。以下是根据标题、描述以及标签提炼出的主要知识点: 1. **Android简介**: - Android操作系统的...

    Android平台开发之旅源码

    了解这些是开始Android开发的必备基础。 2. **Hello World程序**:书中可能包含一个简单的"Hello, World!"程序,用于演示如何创建一个新的Android项目,熟悉XML布局文件和Java活动类的编写,这是每个Android开发者...

    安卓开发教程-中文版Android程序员入门

    了解不同权限类别,以及如何在运行时请求权限,是遵循最佳实践的重要部分。 8. **异步编程**:由于Android应用的主要线程(UI线程)不允许执行耗时操作,因此需要学习如何使用AsyncTask、Handler、Thread或最近的...

    android 开发入门

    《Android开发入门》这篇PDF文档是为初学者精心准备的指南,旨在帮助那些对Android开发感兴趣但毫无经验的人快速上手。这份文档采用中文编写,确保了语言的易读性和理解性,对于中国开发者尤其友好。 Android是谷歌...

Global site tag (gtag.js) - Google Analytics