说一说Android的性能优化
2018-09-10 本文已影响13人
Aron1001
1,UI
UI是最直观的反映APP卡顿的因素,Android系统中,应用程序把经过测量,布局、绘制后的 surface 缓存数据,通过 SurfaceFlinger 把数据渲染到显示屏幕上, 通过 Android 的刷新机制来刷新数据。简单来说就是应用层负责绘制,系统层负责渲染进程间通信把应用层需要绘制的数据传递到系统层服务,系统层服务通过刷新机制把数据更新到屏幕上。
理想的情况下,让人的眼睛不觉的卡顿,每秒传递的帧数要达到60,Android系统每隔16ms发送一次VSYNC信号,1000(1秒)/16=62.5,在这种情况下人的眼睛便不会觉得卡顿,也就是说16ms的绘制时长是符合要求的。如果某一操作的绘制耗时30ms,就会发生丢帧现象,这种现象在动画或者列表滑动中比较常见。
解决方法
- 布局优化
- include merge viewstub的合理使用
- 减少嵌套,推荐使用ConstraintLayout
- 合理使用背景色
- 不能使用ScrollView包裹ListView/GridView/ExpandableListView,因为这样会把ListView的所有Item都加载到内存中,要消耗巨大的内存和cpu去绘制图面。为了较好的UI体验,推荐使用NestedcrollView
- 绘制优化
- onDraw 中不要创建新的局部对象
- onDraw 方法中不要做耗时的任务
2,关于启动
- 冷启动
冷启动是指安装 apk 后首次启动应用程序,或者应用程序上次结束,进程被杀死后重新打开app。
冷启动后系统需要做一下三个任务:
1,加载并启动应用程序
2,启动后立即显示应用程序的空白启动窗口
3,创建应用程序进程
应用程序创建之后,会执行以下操作:- application的初始化
- 启动UI线程
- 创建activity
- inflate view
- onMesure
- onLayout
- onDraw
- 暖启动
暖启动比冷启动时间更短。在暖启动中,系统都会把你的 Activity 带到前台。如果应用程序的 Activity 仍然驻留在内存中,那么应用程序可以避免重复对象初始化、布局加载和渲染,但系统依然会展示闪屏页,直到第一个 Activity 的内容呈现为止。比如:当应用中的 Activities 被销毁,但在内存中常驻时,应用的启动方式就会变为暖启动 。 - 热启动
热启动的启动时间比暖启动还要更短。你比如,我用户 Back 退出应用程序,然后又重新启动,应用程序会再次执行 Activity 的 onCreate()。
解决方法
application 的创建过程中尽量减少耗时的操作,非必须的操作可在异步线程中执行。
3,内存优化
- 匿名内部类/非静态内部类,可以使用android引用机制解决
- 集合类及时置空
- 资源及时关闭(广播,service,文件,eventbus,bitmap)
- context生命周期
- 图片处理(Glide采用的是Lrucache和LruDiskCache)
- 线程池处理多线程
- 集合如果是插入和删除用的多,建议使用 LinkList,如果修改用的多,建议 ArrayList
- 对常量使用 static final,适用于基本类型和 String 常量
- 使用增强的 for 循环语法(foreach)
- 数据量比较大或者内存比较宽裕考虑 HashMap,其他建议使用 SpareArray
- 避免在Service#onStartCommand()/onBind()方法中执行耗时操作,如果有需求,应改为IntentService,或采用其他异步机制完成。
- 避免在BroadcastReceiver#onReceive()中执行耗时操作,如果有耗时工作,应该创建IntentService完成,而不应该在BroadcastReceiver内创建子线程去做。
- 不要在Android的Application地对象中缓存数据。基础组件之间的数据共享使用Intent机制,也可以使用SharedPreferences等数据持久化机制。
- 在Activity中显示对话框或弹出浮层时,尽量使用DialogFragment,而非Dialog/AlertDialog,这样便于随Activity生命周期管理对话框/弹出浮层的生命周期。
- 不要通过Intent在Android基础组件之间传递大数据,可能导致OOM。
- png图片使用tinypng或者类似工具压缩处理,减少包体积。