快、稳、省、小

  • 流程的操作体验
  • 稳定
  • 省电、省流量
  • 安装包小

不好的体验

  • 卡顿
  • 内存泄露、崩溃
  • 代码质量和逻辑差导致耗流量、耗电
  • 安装包过大

快 怎么才能快?

影响卡顿的因素?

  • UI的刷新、绘制
  • 启动,冷启动、热启动、温启动
  • 跳转、页面跳转、前后台切换
  • 即时反馈、点击事件、滑动事件、系统事件等等

UI

UI绘制原理
  • Android 显示过程可以简单概括为:Android 应用程序把经过测量,布局、绘制后的 surface 缓存数据,通过 SurfaceFlinger 把数据渲染到显示屏幕上, 通过 Android 的刷新机制来刷新数据。也就是说应用层负责绘制,系统层负责渲染,通过进程间通信把应用层需要绘制的数据传递到系统层服务,系统层服务通过刷新机制把数据更新到屏幕上。

  • 换一种方式说:Android 系统每隔 16ms 发出 VSYNC 信号,触发对 UI 进行渲染,如果每次渲染都成功,这样就能够达到流畅的画面所需的 60FPS。(注:FPS 表示每秒传递的帧数。)在理想情况下,60 FPS 就感觉不到卡,这意味着每个绘制时长应该在16 ms 左右。如果某个操作花费的时间是 24ms ,系统在得到 VSYNC 信号时就无法正常进行正常渲染,这样就发生了丢帧现象。也就是延迟了,这种现象在执行动画或滑动列表比较常见,还有可能是你的 Layout 太过复杂,层叠太多的绘制单元,无法在 16ms 完成渲染,最终引起刷新不及时.

布局优化
  • 合理使用背景颜色
  • 减少不必要的嵌套层
  • 推荐使用Google的新布局:ConstraintLayout
绘制优化
  • onDraw中不要创建新的布局对象
  • onDraw方法中不要做耗时的任务
  • 刷新,尽量减少不必要的刷新、减少刷新面积
启动优化
冷启动是指安装 apk 后首次启动应用程序,或者应用程序上次结束,进程被杀死后重新打开app
  • Application的创建过程中,尽量较少耗时操作,比如之前onCreat方法中,做了太多事情,比如地图、友盟、Bugly、等SDK init的操作,那我们现在可以先把网络层初始化,把SDK的加载操作放在onResume方法中。
  • 生命周期方法中减少耗时操作
主线程优化
  • 内存优化、避免内存泄漏
那些地方会引起内存泄露?
  • 集合类泄露,集合list.add()之后,如果不用了尽量list.clear()之后再list = null

  • 单例、静态变量 单例引起的内存泄漏,通常是由于引用的context是生命周期短造成的,也就是说生命周期长的持有了生命周期短的引用,造成了内存泄漏。比如Toast,我们传入的是MainActivity,但MainActivity没有用了,需要被销毁,但我们的Tost依然持有其引用导致无法回收,这就导致了内存泄漏。匿名内部类或非静态内部类导致的内存泄漏,这个我们可以采用合理使用JAVA的引用机制来解决,参考Android-强,软,弱,虚引用

  • 匿名内部类、非静态内部类

资源未关闭造成的内存泄露
  • 网络、文件等流忘记关闭
  • 手动注册广播的时候,退出的时候忘记unregisterReceiver()
  • Service执行完毕后,忘记stopSelf()
  • EventBus等观察者模式的框架忘记手动解除注册
  • Bitmap使用完毕,忘记及时Recycle()

哪些文件影响包大小?
  • assets文件夹,不会生成ID,使用AssetManager类接口获取
  • res 会生成ID并映射到R文件,访问的时候直接通过资源ID来
  • META-INF 保存应用的签名信息,签名信息可以验证APK的完整性
  • AndroidMainfest.xml 这个文件用来描述Android应用的配置信息,一些组件的注册信息,可使用权限等等
  • classes.dex Dalvik 字节码程序,让 Dalvik 虚拟机可执行,一般情况下,Android 应用在打包时通过 Android SDK 中的 dx 工具将 Java 字节码转换为 Dalvik 字节码
  • resources.arsc 记录着资源文件和资源ID之间的映射关系,用来根据资源ID寻找资源

减少APK包大小的方式

  • 使用Studio自带的扫描分析工具lint删除无用资源
  • 开启混淆,设置 shrinkResources true和 minifyEnabled true
  • 借助第三方工具如 :乐固加固,360压缩
  • 不要重复使用库
  • 插件化,比如功能模块放在服务器上,按需下载

  • 省电 谷歌推荐使用 JobScheduler,来调整任务优先级等策略来达到降低损耗的目的。JobScheduler 可以避免频繁的唤醒硬件模块,造成不必要的电量消耗。避免在不合适的时间(例如低电量情况下、弱网络或者移动网络情况下的)执行过多的任务消耗电量
  • 省内存 图片压缩
  • 图片尺寸压缩、图片质量压缩 Glide就是采用了 Lrucache 和 LruDiskCache 推荐使用
  • 省 CPU 资源 线程的使用,这里我推荐使用线程池 https://www.jianshu.com/p/07eb2f7db0ee
  • 序列化采用推荐的 Parcelable 代替 Serializable
  • 集合如果是插入和删除用的多,建议使用 LinkList。如果修改用的多,建议 ArrayList
  • 对常量使用 static final,适用于基本类型和 String 常量
  • 使用增强的 for 循环语法(foreach)
  • 避免使用浮点数,浮点数比 Android 设备上的整数慢约2倍
  • 尽可能少用 wrap_content,wrap_content 会增加布局 measure 时计算成本
  • 删除控件中无用的属性
  • 合理使用动画,某些情况下可以用硬件加速方式来提供流畅度,或者采用自定义view代替动画,最后记得在Activity的ondestory()方法中调用Animation.cancle()进行动画停止
  • 考虑 StringBuilder 代替 String
  • 数据量比较大或者内存比较宽裕考虑 HashMap,其他建议使用 SpareArray

更多相关文章

  1. 内存使用总结篇 -- Android内存优化第五弹
  2. Android 性能优化 之谈谈Java内存区域
  3. 深入探索 Android 内存优化(炼狱级别)
  4. Android下常见的内存泄露
  5. 【内存优化】避免使用Enum
  6. Android Valgring检测Native内存泄漏

随机推荐

  1. 基于Android的校园跳蚤市场(二手)的设计与
  2. Android学习及如何利用android来赚钱
  3. Android(安卓)5.1 Settings模块源码分析
  4. 你的Android不好用,都是因为这几点原因
  5. android xml中 颜色透明度(不透明度)参照表
  6. Android修改Eclipse 中的Default debug k
  7. 我也分享一下我Android的收入数据
  8. android之如何使用Android的搜索框架
  9. Android面试经验二:
  10. 【Android休眠】之Android休眠机制