一.高性能App标准:快,稳,省,小
1.快:使用时避免出现卡顿,响应速度快,减少用户等待时间,满足用户期望;
2.稳:降低crash率和ANR率,不要在用户使用过程中崩溃和无响应;
3.省:节省流量和耗电,减少用户使用成本,避免使用时手机发烫;
4.小:安装包小可以降低用户的安装成本;
二.优化范围:卡顿,内存,耗电,网络,apk等方面进行优化
1.卡顿优化:
a.卡顿场景:
1.UI绘制及刷新;
2.启动(安装启动,冷启动,热启动);
3.跳转:页面间切换,前后台切换;
4.响应:按键,系统事件,滑动;
复制代码
b.卡顿根因:
1.界面绘制:
1).layout复杂,不能在16ms内完成渲染,导致丢帧;
2).View的过度绘制,导致某些像素在同一帧时间内被绘制多次;
3).动画在同一时间执行的次数多,导致CPU或GPU负载过重;
2.数据处理:
1).耗时操作在UI线程处理;
2).频繁的GC操作;
复制代码
c.卡顿优化:
1.布局优化:
1).合理使用LinerLayout,RelativeLayout,,FrameLayout,ConstraintLayout等布局容器;
2).使用<include>标签来进行布局复用;
3).使用<merge>标签去除多余层级;
4).使用ViewStub来提高加载速度;
5).避免GPU过度绘制:
a.产生原因:
1.在XML布局中,控件有重叠其都有设置背景;
2.View的onDraw()方法在同一区域绘制多次;
b.解决方案:
1.移除不需要的background;
2.在自定义View的onDraw()方法中,用canvas.clipRect()来指定绘制的区域,防止重叠的组件发生过度绘制;
2.启动优化:
1).UI布局:应用一般会有闪屏页,优化闪屏页的UI布局,可通过Profile GPU Rendering检测丢帧情况;
2).启动加载数据逻辑优化:可采用分部加载,异步加载,延期加载策略来提高应用启动速度;
3).数据准备:数据初始化分析,加载数据可考虑用线程初始化等策略;
3.合理的刷新机制:
1).尽量减少刷新次数;
2).尽量避免后台有高的CPU线程运行;
3).缩小刷新区域;
4.其他:实现动画时,需要根据不同的场景选择合适的动画框架来实现;有些情况下可使用硬件加速方式来提高流畅度;
复制代码
d.分析和解决工具:
1.Profile GPU Rendering:用于查找渲染有问题的界面;
2.Systrace:用于性能数据采样和分析
功能:1.跟踪系统的I/O操作;
2.内核工作队列;
3.CPU负载情况;
4.各种子系统的运行情况等;
5.对于UI显示性能:如动画播放不流畅,渲染卡顿等提供了分析数据;
3.Traceview:用于数据采集和分析
主要获取两种数据:1.单次执行耗时的方法;2.执行次数多的方法
4.Hierarchy Viewer:用于检查布局嵌套和绘制的时间;
5.Android Lint:代码扫描工具,通过代码静态检查来发现代码出现的潜在问题,并给出优化建议;
复制代码
2.内存优化:
a.Android内存管理机制:
1.Java对象生命周期:创建->应用->不可见->不可达->收集->终结->对象空间重新分配;
2.内存分配:实际是对堆的分配和释放,为了控制整个系统的内存控制需要,系统会为每一个应用设置最大限制阈值,超过阈值时会引起内存溢出;
3.内存回收机制:新生代(Edean,Survivor(form,to)),老年代,GC,垃圾回收算法;
复制代码
b.内存泄漏:
1.根本原因:
1).简易描述:长生命周期的对象持有短生命周期的对象的引用,导致GC无法回收该对象;
2).实质理解:没有用的对象到GC Roots是可达的(对象被引用),导致GC无法回收该对象;
2.常见内存泄漏场景:
1).单例/静态变量:具有静态性,它的生命周期等于应用的生命周期,若有Context,则应设为Application的context;
2).匿名内部类/非静态内部类持有外部类的引用:handler使用为静态内部类,使用弱引用;rxjava等;
3).资源未关闭:IO操作,Cursor,广播,EventBus等;
4).集合类:未使用时没及时清理;
5).WebView:使用一次内存就不会被释放,解决方案:为WebView单独开一个进程,使用AIDL与应用的主进程进行通信;
复制代码
c.内存抖动:
1.根本原因:短时间内频繁地创建对象(可能在循环中创建对象),内存为了应对这种情况,会频繁地进行GC操作;频繁的GC会产生大量的暂停时间,会导致界面绘制时间减少,使得多次绘制一帧的时长超过16ms,产生界面卡顿现象;
复制代码
d.内存溢出:
1.根本原因:是指程序在申请内存时,没有足够的内存空间供其使用;
2.如何避免OOM:
1).使用更加轻量的数据结构:如使用ArrayMap/SparseArray替代HashMap,HashMap更耗内存,因为它需要额外的实例对象来记录Mapping操作,SparseArray更加高效,因为它避免了Key Value的自动装箱,和装箱后的解箱操作;
2).便面枚举的使用,可以用静态常量或者注解@IntDef替代;
3).Bitmap优化:
a.尺寸压缩:通过InSampleSize设置合适的缩
b.颜色质量:设置合适的format,ARGB_6666/RBG_545/ARGB_4444/ALPHA_6,存在很大差异
c.inBitmap:使用inBitmap属性可以告知Bitmap解码器去尝试使用已经存在的内存区域,新解码的Bitmap会尝试去使用之前那张Bitmap在Heap中所占据的pixel data内存区域,而不是去问内存重新申请一块区域来存放Bitmap。利用这种特性,即使是上千张的图片,也只会仅仅只需要占用屏幕所能够显示的图片数量的内存大小,但复用存在一些限制,具体体现在:在Android 4.4之前只能重用相同大小的Bitmap的内存,而Android 4.4及以后版本则只要后来的Bitmap比之前的小即可。使用inBitmap参数前,每创建一个Bitmap对象都会分配一块内存供其使用,而使用了inBitmap参数后,多个Bitmap可以复用一块内存,这样可以提高性能;
4).StringBuilder替代String: 在有些时候,代码中会需要使用到大量的字符串拼接的操作,这种时候有必要考虑使用StringBuilder来替代频繁的“+”;
5).避免在类似onDraw这样的方法中创建对象,因为它会迅速占用大量内存,引起频繁的GC甚至内存抖动;
6).减少内存泄漏也是一种避免OOM的方法;
复制代码
e.优化内存空间:
1.对象引用:根据业务需求合理使用 强 软 弱 虚 四种引用类型;
2.减少不必要的内存开销:注意自动装箱,增加内存复用,如:有效利用系统自带的资源,视图复用,对象池,Bitmap对象复用;
3.使用最优的数据类型:如ArrayMap数据结构,避免使用枚举类型,使用缓存Lrucache等;
4.图片内存优化:可设置图片位图规格,根据采样因子做压缩,用一些图片缓存方式对图片进行管理等;
复制代码
f.内存分析工具:
1.Profiler(系统自带):
1).主要用来观察内存,网络,CPU温度等;
2).可识别出内存泄漏和内存抖动导致应用的卡顿,ANR和crash;
3).可生成图表,查看内存的使用情况,还能强制内存回收和跟踪内存分配;
2.MAT
1).通过DDM或Memory Monitor生成格式为hprof的堆存储文件;
2).通过深入分析疑似发生内存时所生成的hprof来确定是否发生内存泄漏;
3.LeakCanary:基于MAT开发的内存泄漏插件;
复制代码
3.耗电优化—敬请期待
4.网络优化—敬请期待
5.Apk优化—敬请期待
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END