Android应用提升性能和用户体验

出色的用户体验有三个特征:速度快、响应及时以及无缝。下面的信息帮助你的应用如何能够在 Android 上实现这些特征。
一、速度快
你不能假设手机与桌面系统和服务器一样提速,更多的是你要关注你的代码是否高效。
编写高效的 Android 代码,应遵循两个原则:
不要做不必要的事
不要分配不必要的内存
以下是一些达到此目标的小技巧(有一些技巧是与 oo 的原则冲突,斟酌使用场景):
1 、避免建立对象
例如, int 数组比 Integer 数组好,同理,这适用于所有基本类型的组合
2 、使用本地方法
不要吝惜使用 String.indexOf(), String.lastIndexOf() 等特殊实现的方法 (specialty methods) 。这些方法都是使用 C/C++ 实现的
3 、使用实现类比接口好
Map myMap1 = new HashMap();
HashMap myMap2 = new HashMap();
调用一个接口的引用会比调用实体类的引用多花费一倍的时间
4 、不用 getter setter
应该直接访问变量
5 、将成员变量缓存到本地
for (int i = 0; i< this.mCount; i++)           
    dumpItem(this.mItems );
最好改成这样:
  int count = this.mCount;
  Item[] items = this.mItems;
  for (int i = 0; i< count; i++) dumpItems(items);
另外,永远不要在for的第二个条件中调用任何方法
6、给常量加上final
static int intVal = 42;
static String strVal = “Hello, world!”;
  编译器会生成一个叫做的初始化类的方法,当类第一次被使用的时候这个方法会被执行。方法会将42赋给intVal,然后把一个指向类中常量表的引用赋给strVal。当以后要用到这些值的时候,会在成员变量表中查找到他们。
static final int intVal = 42;
static final String strVal = “Hello, world!”;
  现在,类不再需要方法,因为在成员变量初始化的时候,会将常量直接保存到类文件中。用到intVal的代码被直接替换成42,而使用strVal的会指向一个字符串常量,而不是使用成员变量。
7、谨慎使用foreach
  foreach可以用在实现了Iterable接口的集合类型上。foreach会给这些对象分配一个iterator,然后调用hasNext()next()方法。你最好使用foreach处理ArrayList对象,但是对其他集合对象,foreach相当于使用 iterator
8、避免使用枚举
  枚举变量非常方便,但不幸的是它会牺牲执行的速度和并大幅增加文件体积
9、将内部类需要访问的外部变量或方法声明在包范围内
public class Foo {
  private int mValue;
  public void run() {
      Inner in = new Inner();
      mValue = 27;
      in.stuff();
  }
  private class Inner {
      void stuff() {
      System.out.println(Foo.this.mValue);
      }
  }
}
Foo$Inner是一个完全独立的类,它要直接访问Foo的私有成员是非法的。编译器会自动生成一个方法:
/*package*/ static int Foo.access$100(Foo foo) {
  return foo.mValue;
}
内部类在每次访问”mValue”方法时,都会调用这个静态方法。同理,内部类要访问私有方法也是如此。
10、避免使用浮点数
嵌入式处理器通常没有支持浮点运算的硬件,所有对”float””double”的运算都是通过软件实现的
通过将内部类访问的变量和函数声明由私有范围改为包范围,我们可以避免这个问题。这样做可以让代码运行更快,并且避免产生额外的静态方法。(遗憾的是,这些成员变量和方法可以被同一个包内的其他类直接访问,这与经典的OO原则相违背。因此当你设计的时候应该谨慎使用这条优化原则)
二、响应及时
1、将耗时工作交到子线程
2、如果你的程序在后台处理用户的输入,给出一个你正在工作的提示(ProgressBar(进度条)ProgressDialog(进度对话框)是很好的选择)
3、如果是游戏,把计算步骤放在子线程中
三、无缝
1、不要丢失数据,继承onPause()方法
2、利用ContentProvider来共享数据
3、不要打断用户,使用通知
随着手机平台的发展和所提供应用的提升,质量成为应用成功的最重要因素。如果那些应用无法提供强大的功能和稳定的用户体验,那就会很快被用户卸载。开发者需要记住的是,虽然Android智能手机和平板电脑的速度日益提升,但其应用仍然运行在资源有限的环境中,其电池及处理器性能与最新的台式电脑、手提电脑仍存在差距。以下是某些优化应用运行效果的方法:
我们先来阐述某些让应用反应灵敏的编程技巧。

技巧1:从优秀的编程开始

要采用已为用户所接受的运算法则和标准的设计样式,这些被人们长期使用的编程法则也同样适用于Android应用,尤其当这些应用使用内在设备服务时。
比如,假设你编写的应用需要以地理定位服务为基础。只需要在必要时开始注册进行位置更新,在无需更新信息时,确保应用停止更新进程。这会帮助节省设备的电量和系统处理器的负担。

技巧2:保持应用的灵活性
通过使用AsyncTask、IntentService或自定义背景服务来保持应用的灵活性。使用加载器来简化加载时间较长数据的状态管理,比如光标。不可让应用在其他进程进行时显得缓慢或完全静止。
如果某些操作需要一定的时间和资源,应当将这个进程单独分离出来异步处理,这样你的应用才能够保持流畅的运行。可以运用这种方法的操作包括:磁盘读写,访问内容供应方、数据库和网络,其他需要较长时间的任务。

技巧3:使用最新的Android SDK版本和API
保持应用的更新,使用Android平台提供的最新内容。随着Android平台的发展,它也在逐步改善中。某些功能被移除,或者替换成更好的选项。其核心API中的漏洞已修复,整个API性能已得到提升。该平台已引入装载器之类的新API,帮助开发者编写更为稳定和反应灵敏的应用。
Android 3.0应用支持硬件加速,你可以加以应用。应当理解的是,最佳的表现情况会随着时间逐渐改变。睿智的开发者会更新平台发布的最新内容和API。

技巧4:检查Strict Mode
你可以使用称为“StrictMode”的Android API来查找编程中的问题。StrictMode会帮助你识别应用是否正在耗费内存,也可以帮你检查应用是否正在尝试开展漫长的模块化操作。
StrictMode类(注:即android.os.StrictMode)与Android 2.3同期发布。

技巧5:在发布之前停用或最小化调试和诊断
你在Android应用的开发中可能会将某些调试代码构建其中。在应用发布之前确保这些功能被最小化或完全停用。
接下来,让我们来讨论如何用优秀的用户界面设计原则让你的应用加载速度更快。

技巧6:保持布局简洁自然
简洁自然的布局会加快加载速度。不要让屏幕布局中充斥过多不必要的内容。花点时间开发用户可以有效使用的简洁用户界面,不要将过多的功能性内容塞入单个屏幕中。这不仅对应用表现有帮助,而且会帮助用户更有效地使用应用。
分割内容可以帮助划分用户界面功能性,同时不牺牲应用在各种不同设备上的灵活性。

技巧7:根据目标设备调整应用资源
根据特定的设备配置来调整资源,这样它们就能够有效地加载。在图像资源方面,这个显得尤为重要。如果你的应用中有大型的图片资源需要加载,那么要做好调整。
另一个技巧是,当以许多种设备为目标时,保持应用包文件大小合适,只需要在其中包含应用运行所需的核心资源即可,然后让用户根据具体设备下载应用其他内容。

技巧8:使用Hierarchy Viewer工具
Hierarchy Viewer工具可以帮助你解除应用布局中的漏洞。它还提供了许多有价值的信息,比如每个View控制需要多长的时间。找到问题所属领域,这样解决问题会更加简单。

技巧9:使用layoutopt工具
layoutopt工具是个简单的命令行工具,可以帮助你识别不必要的控制和其他让你布局资源崩溃的事项,提升其性能。它可以帮助你找到不必要的多余布局控制。较少和较浅布局可优化应用运行性能。
最后,在自认为应用达到最好状况时,对其进行测试。

技巧10:使用Traceview和其他Android应用压缩工具
Android SDK中有许多可以压缩应用的工具。可能最流行的工具就是Traceview,这个图像工具可以帮助你调试和找到应用的性能问题。

结语
目前有许多方法可以让你的Android应用运行加速。有些涉及到使用某种具体的运算法则,其他依靠某些真正的调试和运行监管技术。Android平台中有许多种免费的工具可以用来帮助跟踪和调整应用中的表现问题。你已经知道了以上10种技巧,现在可以尝试使用它们!
由于本人现在在一家专职做网游的公司,所以现在需要使用一些方法对现运营的网游代码进行精简和优化,那么就要使用到Android sdk中提供的一款很好的检视工具Android TraceView、下面先给出对此的解释:然后讲解实现的详细步骤和需要特别注意的一点!
什么是TraceView?先看下百度出来的解释吧:
Traceviewandroid平台配备一个很好的性能分析的工具。它可以通过图形化的方式让我们了解我们要跟踪的程序的性能,并且能具体到method
  关于Traceview的使用
  首先,必须在程序当中加入代码,以便生成trace文件,有了这个trace文件才可以将其转化为图形。
  要添加的代码如下:
  Java代码
  // start tracing to "/sdcard/yourActivityTrace.trace"
  Debug.startMethodTracing("yourActivityTrace");
    // ... // stop tracing Debug.stopMethodTracing();
   // start tracing to "/sdcard/yourActivityTrace.trace" Debug.startMethodTracing("yourActivityTrace");
   // ... // stop tracing Debug.stopMethodTracing();
  Google Dev Guide当中说可以在activityonCreate()中添加Debug.startMethodTracing(), 而在onDestroy()中添加Debug.stopMethodTracing(),但是在实际的测试时发现这种方式其实并不好用,因为通常情况下我们的activityonDestroy()是由系统决定何时调用的,因此可能等了很长时间都不会得到这个trace文件。因此决定在onStop()中来调用Debug.stopMethodTracing()。这样当我们切换到其它activity或者点击home键的时候onStop()就会被调用,我们也就可以得到完整的trace file
  在运行程序之前,首先要保证我们的AVD是一个带有SD cardAVD,这样才能使trace文件保存到/sdcard/...当中。运行后可以任意做一些操作,然后点击home键。这是通过DDMS file explore就可以看到/sdcard/目录下有一个trace文件,现在把这个文件copy到电脑上指定的目录,假设是C:/tracefile 目录下。
  可以通过命令行来执行traceview,进入tools目录后,执行
  traceview C:/tracefile/yourActivityTrace.trace
  之后就可以看到图形了,接下来就是按照Google Dev Guide中的解释去分析图形就OK了。
下面来看如何实现以及需要注意的地方:
  实现的步骤分为三步:1.必须先在我们的模拟器中创建sdCard 2.将我们的调试代码嵌入工程;3.利用TraceView来观察和分析代码情况;
1.对于创建模拟器的sdCard这里写出两种方式:
第一种:我们在eclipse中创建avd的时候的时候 在选择api下面有个 Sd Card 的选项,第一项填入创建sdcard的大小即可。

 
第二种: cmd  命令! 打开 cmd  并且 cd  android sdk tool  路径下;(或者在环境变量 Path 中将 sdk tool 路径配置上,然后重新打开 cmd
使用 mksdcard -l mycard 1024M F:/mysdcard.img 创建了一个 1G sdcard
使用 emulator -avd my_android -sdcard F:/mysdcard.img 激活 sdcard!
最后在 eclipse Preferences-->Android-->Launch 加入 -sdcard F:/mysdcard.img  (此步骤就是在第一种创建方式中添加 sdcard 的支持)
备注 1
     如果 sdcard 分配的空间太小,则程序追踪文件就一直记录到 sd 储蓄卡容量慢为止,所以调试前,要为程序生成一个适当的 SD 存储卡也较为重要 , 因为程序运行时间越长,这个追踪文件也就越大。

备注 2;
( 如果第二种创建方式中的第二部激活出现  emulator: ERROR: the user data image is used by another emulator. aborting ,请关闭模拟器,或者进入目录:  /Documents and Settings /  用户  / .android / AVD / * 设备 * / ( 比如我的目录是: C:/Documents and Settings/Administrator/.android/avd/android2.0.avd)
然后删去以 .lock 结尾的文件夹就行 ( 我简单解释下为什么要删除这些文件呢,其实 .lock 是加锁,如果程序崩溃等原因导致无法清除这些以 .lock 结尾的文件夹,就会出现这个问题,也就是这个 avd 的锁没有被释放,导致 avd   manager 以为这个 avd 正在使用当中。 ))

2. 将我们的调试代码嵌入工程
正如我们百度到的说明一样,在程序运行的开端加上   Debug.startMethodTracing("yourActivityTrace");   然后在 onPause ()中调用 Debug.stopMethodTracing();  为什么要将结束写在 onPause ()中而不写在 onStop (),那么如果你去看 api 的话,你会看到, Api 中介绍 onPause ()会在你返回和点击 home 按键后触发,而 onStop ()一般是由系统来触发,当该程序处于后台的时候,而且当内存紧张的时候,可能会调用,但是可能永远不会调用到!
备注:要记住当把调试代码加入项目中以后不要立即运行项目,而是必须在 AndroidMainfest.xml 中定义一条 " 写入 SD 卡的权限 " 那么添加权限的代码如下:
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
因为咱们的调试代码会在 SD 卡中生成一个追踪文件,也就是往 SD 卡中写入了数据,所以需要声明一条权限。这里必须注意哦!



3. 运行项目并且退出项目从而得到的追踪文件,利用 TraceView 来进行分析代码运行状况:
打当正常运行了项目并且点击返回或者 home 按键就会在  sdcard 中生成一个 .trace 的文件。 sdcard  目录 在 eclipse 下,点击 :
windows-show view-other-android-File explorer

 
右上角的两个箭头,第一个表示从模拟器 sdcard 导出文件,第二个表示从 PC 上导入文件到 sdcard 中、 “—” 代表删除  .....
然后我们通过 cmd 来运行生成的追踪文件  traceview C:/name      追踪文件所在的路径放在 C 盘,放在 C 盘以外别的盘的话我这里是无法正常打开 traceview 的不知道什么原因。    name  表示生成的 .trace 文件, cmd 的时候不需要输入 .trace 后缀  ; 然后会出现 TraceView 的分析窗口 ;
【cmd  命令! 打开 cmd  并且 cd  android sdk tools  路径下;(或者在环境变量 Path 中将 sdk tool 路径配置上,然后重新打开 cmd )】
注意 1 :如果出现一下图片这种内存溢出的问题 ;

 
解决方法:到 SDK  下的 tools  下 找到   traceview.bat  文件,鼠标右键 - 编辑(或者记事本打开),最后一行替换成这样:
call java -Xms128m -Xmx512m -Djava.ext.dirs=%javaextdirs% -jar %jarpath% %*
注意 2 :如果出现路径不对的问题:
例如:我的  himi.trace  放在了 C , 那么我的 cmd 命令是 :   traceview c:/himi    然后回车!
但是这里要小心,因为  /h  这样可能被认为是转义字符!!!为了避免可以尽可能不要使用 h,n,r,t, 等等成为名字的头字母,当然还有一种就可以完全避免这种问题,例如还是我的 C himi.trace  文件,可以写 cmd 命令的时候写成:  traceview c://himi    嘿嘿 ~ 要注意细节。


OK ,其次说说,如何提高 Android 的效率,也就是如何来优化 Android 的性能:
1 http gzip 压缩,设置连接超时时间和响应超时时间
http 请求按照业务需求,分为是否可以缓存和不可缓存,那么在无网络的环境中,仍然通过缓存的 httpresponse 浏览部分数据,实现离线阅读。
2.listview  性能优化
1). 复用 convertView
getItemView 中,判断 convertView 是否为空,如果不为空,可复用。如果 couvertview 中的 view 需要添加 listerner ,代码一定要在 if(convertView==null){} 之外。
2). 异步加载图片
item 中如果包含有 webimage ,那么最好异步加载
3). 快速滑动时不显示图片
当快速滑动列表时( SCROLL_STATE_FLING ), item 中的图片或获取需要消耗资源的 view ,可以不显示出来;而处于其他两种状态( SCROLL_STATE_IDLE SCROLL_STATE_TOUCH_SCROLL ),则将那些 view 显示出来
4).BaseAdapter 避免内存溢出
如果 BaseAdapter 的实体类有属性非常消耗内存,可以将保存到文件;为提高性能,可以进行缓存,并限制缓存大小。
3. 使用线程池,分为核心线程池和普通线程池,下载图片等耗时任务放置在普通线程池,避免耗时任务阻塞线程池后,导致所有异步任务都必须等待
4. 异步任务,分为核心任务和普通任务,只有核心任务中出现的系统级错误才会报错,异步任务的 ui 操作需要判断原 activity 是否处于激活状态
5. 尽量避免 static 成员变量引用资源耗费过多的实例 , 比如 Context
6. 使用 WeakReference 代替强引用,弱引用可以让您保持对对象的引用,同时允许 GC 在必要时释放对象,回收内存。对于那些创建便宜但耗费大量内存的对象,即希望保持该对象,又要在应用程序需要时使用,同时希望 GC 必要时回收时,可以考虑使用弱引用。
7. 超级大胖子 Bitmap
及时的销毁 (Activity onDestroy 时将 bitmap 回收,在被 UI 组件使用后马上进行回收会抛  RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap)
设置一定的采样率 ( 有开发者提供的图片无需进行采样,对于有用户上传或第三方的大小不可控图片,可进行采样减少图片所占的内存 ) ,从服务端返回图片,建议同时反馈图片的 size
巧妙的运用软引用
drawable 对应 resid 的资源, bitmap 对应其他资源
任何类型的图片,如果获取不到(例如文件不存在,或者读取文件时跑 OutOfMemory 异常),应该有对应的默认图片(默认图片放在在 apk 中,通过 resid 获取);
8. 保证 Cursor  占用的内存被及时的释放掉,而不是等待 GC 来处理。并且  Android 明显是倾向于编 程者手动的将 Cursor close
9. 线程也是造成内存泄露的一个重要的源头。线程产生内存泄露的主要原因在于线程 生命周期的不可控
10. 如果 ImageView 的图片是来自网络,进行异步加载
11. 应用开发中自定义 View 的时候,交互部分,千万不要写成线程不断刷新界面显示,而是根据 TouchListener 事件主动触发界面的更新
12.Drawable
ui 组件需要用到的图片是 apk 包自带的,那么一律用 setImageResource 或者 setBackgroundResource ,而不要根据 resourceid
注意: get(getResources(), R.drawable.btn_achievement_normal) 该方法通过 resid 转换为 drawable ,需要考虑回收的问题,如果 drawable 是对象私有对象,在对象销毁前是肯定不会释放内存的。
13. 复用、回收 Activity 对象临时的 activity 及时 finish 主界面设置为 singleTask 一般界面设置为 singleTop
14. 位置信息获取用户的地理位置信息时,在需要获取数据的时候打开 GPS ,之后及时关闭掉
15. onResume 时设置该界面的电源管理,在 onPause 时取消设置
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值