如何对Android 应用进行性能分析以及优化

 

这个作者做了很多片性能优化的文章,建议看完
https://www.jianshu.com/p/da2a4bfcba68

我们常见的App优化会涉几个方面

一般来说, 有以下几个方面:

  1. App启动优化
  2. 布局优化
  3. 响应优化
  4. 内存优化
  5. 电池使用优化
  6. 网络优化

 

一、APP启动优化类:

在APP冷启动、热启动、温启动过程中不要进行耗时的操作。

二、布局优化类:

1.尽量减少布局层级和复杂度

(1)尽量不要嵌套使用RelativeLayout.

(2)尽量不要在嵌套的LinearLayout中都使用weight属性.

(3)Layout的选择, 以尽量减少View树的层级为主.

(4)去除不必要的父布局.

(5)善用TextView的Drawable减少布局层级

(6)如果H Viewer查看层级超过5层, 你就需要考虑优化下布局了~

2.善用Tag

(1):使用include来重用布局.

(2):使用来解决include或自定义组合ViewGroup导致的冗余层级问题. 例如本例中的RepoItemView的布局文件实际可以用一个标签来减少一级.

(3):显示时才去加载出来

3.ListView优化

(1)contentView复用

(2)引入holder来避免重复的findViewById.

(3)分页加载

4.使用Layout Inspector,用于布局优化

5.避免过于复杂的布局如果我们的UI布局层次太深, 或是自定义控件的onDraw中有复杂运算, CPU的相关运算就可能大于16ms, 导致卡顿.

6.避免过度绘制(Overdraw)(Overdraw: 用来描述一个像素在屏幕上多少次被重绘在一帧上.通俗的说: 理想情况下, 每屏每帧上, 每个像素点应该只被绘制一次, 如果有多次绘制, 就是Overdraw, 过度绘制了)

所谓Overdraw, 就是在一个像素点上绘制了多次. 常见的就是:

(1)绘制了多重背景.

(2)绘制了不可见的UI元素.

可以通过如下方式去掉window的背景.

设置主题:

@null

或是代码设置, 在onCreate中:

getWindow().setBackgroundDrawable(null);

UI线程的复杂运算会造成UI无响应, 当然更多的是造成UI响应停滞, 卡顿.

 

7.StrictMode的使用

StrictMode用来基于线程或VM设置一些策略, 一旦检测到策略违例, 控制台将输出一些警告,包含一个trace信息展示你的应用在何处出现问题.

通常用来检测主线程中的磁盘读写或网络访问等耗时操作.

 

三、响应优化类:

ANR的处理针对三种不同的情况, 一般的处理情况如下

(1)主线程阻塞的:开辟单独的子线程来处理耗时阻塞事务.

(2)CPU满负荷, I/O阻塞的:I/O阻塞一般来说就是文件读写或数据库操作执行在主线程了, 也可以通过开辟子线程的方式异步执行.

(3)内存不够用的:增大VM内存, 使用largeHeap属性, 排查内存泄露(这个在内存优化那篇细说吧)等.

 

四、内存优化类:

避免频繁的GC执行GC操作的时候,任何线程的任何操作都会需要暂停,等待GC操作完成之后,其他操作才能够继续运行, 故而如果程序频繁GC, 自然会导致界面卡顿.

 

导致频繁GC有两个原因:

  1. 内存抖动(Memory Churn), 即大量的对象被创建又在短时间内马上被释放.
  2. 瞬间产生大量的对象会严重占用Young Generation的内存区域, 当达到阀值, 剩余空间不够的时候, 也会触发GC. 即使每次分配的对象需要占用很少的内存,但是他们叠加在一起会增加Heap的压力, 从而触发更多的GC.

这些GC操作可能会造成上面说到的丢帧, 就会让用户感知到卡顿了.

如下:

如何对Android 应用进行性能分析以及优化_第1张图片

五、网络优化类:

1.减少网络数据获取的频次这就减少了radio的电量消耗, 控制电量使用.

2.减少获取数据包的大小可以减少流量消耗,也可以让每次请求更快, 在网络情况不好的情况下也有良好表现, 提升用户体验.

3.Gzip压缩使用Gzip来压缩request和response, 减少传输数据量, 从而减少流量消耗.

4.考虑使用Protocol Buffer代替JSON从前我们传输数据使用XML, 后来使用JSON代替了XML, 很大程度上也是为了可读性和减少数据量(当然还有映射成POJO的方便程度).

Protocol Buffer是Google推出的一种数据交换格式.

如果我们的接口每次传输的数据量很大的话, 可以考虑下protobuf, 会比JSON数据量小很多.

5.控制图片的大小:图片相对于接口请求来说, 数据量要大得多. 故而也是我们需要优化的一个点.

我们可以在获取图片时告知服务器需要的图片的宽高, 以便服务器给出合适的图片, 避免浪费.

6.网络缓存适当的缓存, 既可以让我们的应用看起来更快, 也能避免一些不必要的流量消耗.

7.打包网络请求当接口设计不能满足我们的业务需求时. 例如可能一个界面需要请求多个接口, 或是网络良好, 处于Wifi状态下时我们想获取更多的数据等.

这时就可以打包一些网络请求, 例如请求列表的同时, 获取Header点击率较高的的item项的详情数据.可以通过一些统计数据来帮助我们定位用户接下来的操作是高概率的, 提前获取这部分的数据.

8.监听相关状态并进行相应的优化:

通过监听设备的状态:

(1)休眠状态

(2)充电状态

(3)网络状态

结合JobScheduler来根据实际情况做网络请求. 比方说Splash闪屏广告图片, 我们可以在连接到Wifi时下载缓存到本地; 新闻类的App可以在充电, Wifi状态下做离线缓存.

9.弱网下的操作

(1)压缩/减少数据传输量

(2)利用缓存减少网络传输

(3)针对弱网(移动网络), 不自动加载图片

(4)界面先反馈, 请求延迟提交:例如, 用户点赞操作, 可以直接给出界面的点赞成功的反馈, 使用JobScheduler在网络情况较好的时候打包请求.

你可能感兴趣的:(Android,性能优化)