根据Android应用的开发特点,最有可能成为系统瓶颈的地方有如下:
- 网络操作
手机客户端一般都会应用到大量的网络IO的访问,由于网络环境的不确定性和网络速度的影响,网络操作的速度可能是非常缓慢的,因此,如果不进行特殊的优化,将很可能成为影响性能的杀手。
- 磁盘IO
如果需要读写的文件较大,或者用户的SD卡等外部存储设备读写速度很慢,都有可能极大影响用户体验。
- 数据库
大部分的程序都是离不开数据库的,如果处理的数据是海量的,那将会花费太多的时间。
- 大量的计算
由于手机的计算能力有限,大量的计算可能会造成CPU被某个线程“独占”从而影响其他任务的运行。并且如果非常高频率的使用CPU,也会影响到手机发热、电池损耗。严重的话,用户可能会毫不留情的删除你的应用!
以上的4个部分,除了代码级别的优化外(如使用NIO等新的类库进行IO访问),还可以通过新线程来进行分支处理。从而不影响绘制用户UI的主线程的运行,给用户良好的应用体验。
- 内存消耗
- View的频繁绘制、解析
在ListView等控件中,用户可能都会大量使用同一个View,如果每次都生成新的View对象,将是对CPU和内存资源的极大浪费。因此需要有效的管理和重用,才能提高程序的运行速度,防止浪费。
- 线程的调度
频繁的开启新的线程,回收线程会造成内存的极大浪费。因此使用线程池来管理和重用线程是非常重要的。
以上的三个部分可以分别使用Cache和Pool的机制的来解决问题,例如ListView中,可能上下滑动会加载到同几张图片和View,那么那几张图片可以使用Cache来管理起来,防止图片被过早的释放而频繁的调用IO来获取同一张图片。而View则可以使用Pool管理(我更喜欢称为Pool而不是Cache,因为Cache是缓存、是保持对对象的引用的持有防止对象被过早的清理。而Pool是池,是用来暂存一些对象以便重用的)。
- 锁竞争
对于高并发的程序来说,如果存在激烈的竞争,那就必然需要使用一定的机制来防止一些不必要的麻烦。但是锁机制的开销是很大的,如果这些开销都是和应用需求无关的开销,那么拜拜浪费宝贵的硬件资源,还带不来任何好处。
总结建议:
- 使用线程做工作量大的事。
- 使用Cache缓存来管理可能在将来某个时刻(很近的时刻)还需要使用的对象。
- 使用Pool来管理需要大量复用的对象。
- 使用更新的类(尤其是字符串、数组、容器)来完成工作。
- 在不考虑多线程的情况下,尽量使用没有锁机制的类。