一、性能优化的好处?
-
减少 OOM,可以提高程序的稳定性。
-
减少卡顿,提高应用流畅性。
-
减少内存占用,提高应用后台存活性。
-
减少程序异常,降低应用 Crash 率, 提高稳定性。
二、减少 OOM,可以提高程序的稳定性
1、减少 OOM
在应用开发阶段我比较喜欢用 LeakCanary
这款性能检测工具,好处是它能实时的告诉我具体哪个类发现了内存泄漏(如果你对 LeakCanary 的原理了解的话,可以说一说它是怎么检测的)。
还有我们要明白为什么应用程序会发送 OOM ,又该怎么去避免它?
发生 OOM 的场景是当申请 1M 的内存空间时,如果你要往该内存空间存入 2M 的数据,那么此时就会发生 OOM。
在应用程序中我们不仅要避免直接导致 OOM 的场景还要避免间接导致 OOM 的场景。间接的话也就是要避免内存泄漏的场景。
内存泄漏的场景是这个对象不再使用时,应用完整的执行最后的生命周期,但是由于某些原因,对象虽然已经不再使用,仍然会在内存中存在而导致 GC 不会去回收它,这就意味着发生了内存泄漏。(这里可以介绍下 GC 回收机制,回收算法,知识点尽量往外扩展而不脱离本题)
2、最后在说一下在实际开发中避免内存泄漏的场景:
1、资源型对象未关闭: Cursor,File
2、注册对象未销毁: 广播,回调监听
3、类的静态变量持有大数据对象
4、非静态内部类的静态实例
5、Handler 临时性内存泄漏: 使用静态 + 弱引用,退出即销毁
6、容器中的对象没清理造成的内存泄漏
7、WebView: 使用单独进程
三、减少卡顿
怎么减少卡顿? 那么我们可以从 2 个原理方面来探讨卡顿的根本原因,第一个原理方面是绘制原理,另一个就是刷新原理。
1、绘制原理:
![](https://img.haomeiwen.com/i26777047/310f285721ba091f.png)
2、刷新原理:
View 的 requestLayout 和 ViewRootImpl##setView 最终都会调用 ViewRootImpl 的 requestLayout 方法,然后通过 scheduleTraversals 方法向 Choreographer 提交一个绘制任务,然后再通过 DisplayEventReceiver 向底层请求 vsync 垂直同步信号,当 vsync 信号来的时候,会通过 JNI 回调回来,在通过 Handler 往消息队列 post 一个异步任务,最终是 ViewRootImpl 去执行绘制任务,最后调用 performTraversals 方法,完成绘制。
详细流程可以参考下面流程图:
![](https://img.haomeiwen.com/i26777047/5bd4f691a98a73a1.png)
3、卡顿的根本原因:
从刷新原理来看卡顿的根本原理是有两个地方会造成掉帧:
- 一个是主线程有其它耗时操作,导致doFrame 没有机会在 vsync 信号发出之后 16 毫秒内调用;
- 还有一个就是当前doFrame方法耗时,绘制太久,下一个 vsync 信号来的时候这一帧还没画完,造成掉帧。
4、怎么避免卡顿:
一定要避免在主线程中做耗时任务,总结一下 Android 中主线程的场景:
- 减少刷新次数
- 避免非必要的刷新
- 尽量使用属性动画,它减少了自身的重绘。
- 减少页面布局的层级;
- 父布局套子布局也是尽量只设置其中一个背景
还有一个最重要的就是避免内存抖动,不要在短时间内频繁的内存分配和释放。
5、布局优化分析工具:
![](https://img.haomeiwen.com/i26777047/158b1a5a1499edc7.png)
6、优化方案:
![](https://img.haomeiwen.com/i26777047/f29dfced8b0437b4.png)
四、减少内存占用
1、AutoBoxing(自动装箱): 能用小的坚决不用大的。
2、内存复用
3、使用最优的数据类型
4、 枚举类型: 使用注解枚举限制替换 Enum
5、图片内存优化(这里可以从 Glide 等开源框架去说下它们是怎么设计的)
6、选择合适的位图格式
7、bitmap 内存复用,压缩
8、图片的多级缓存
9、基本数据类型如果不用修改的建议全部写成 static final,因为 它不需要进行初始化工作,直接打包到 dex 就可以直接使用,并不会在 类 中进行申请内存
10、字符串拼接别用 +=,使用 StringBuffer 或 StringBuilder
11、不要在 onMeause, onLayout, onDraw 中去刷新 UI
12、尽量使用 C++ 代码转换 YUV 格式,别用 Java 代码转换 RGB 等格式,真的很占用内存
五、其他优化
1、你们 APK 有多大?有做过 APK 体积相关的优化吗?
![](https://img.haomeiwen.com/i26777047/f7c53f0c75a3985c.png)
2、有做过日志优化吗?
![](https://img.haomeiwen.com/i26777047/06824a45446781b6.png)
3、你们项目的耗电量怎么样? 有做过优化吗?
在没有优化之前持续工作 30 分钟的耗电量是 8%, 优化后是 4%。
![](https://img.haomeiwen.com/i26777047/eb52a71946dfa556.png)
4、你在项目中有做过自定义 View 吗?有对它做过什么优化?
有做过。比如重复绘制,还有大图长图有过优化。
![](https://img.haomeiwen.com/i26777047/36854eea3f5b6b29.png)
5、ANR
![](https://img.haomeiwen.com/i26777047/4eb45c2d61fc6281.png)
6、后台存活
![](https://img.haomeiwen.com/i26777047/56aa4da7a1030085.png)
7、说说你在项目中网络优化?
![](https://img.haomeiwen.com/i26777047/23751840c9817182.png)
8、你在项目中有用过哪些存储方式? 对它们的性能有过优化吗?
主要用过 sp,File,SQLite 存储方式。其中对 sp 和 sqlite 做了优化。
![](https://img.haomeiwen.com/i26777047/70099c708859e092.png)
参考:https://blog.csdn.net/apple_4872330/article/details/125670555
网友评论