Android性能 - 取经之路

在这里插入图片描述

整理自网络

Android性能 - 启动

  • Android程序的启动分类

  • 冷启动

    1. 加载启动app
    2. 展示空白window页面
    3. 创建app进程
    4. 创建app对象
    5. 启动主线程
    6. 创建启动activity对象
    7. 加载view
    8. 布置屏幕
    9. 第一次绘制
  • 启动优化方向

    1. 替换window页面背景 <障眼法>

    2. 避免启动的密集初始化

      常常使用的multiDex初始化,第三方组件初始化

      利用欢迎页和闪屏页时间完成初始化

    3. 避免耗时操作和深嵌套布局

Android性能 - 布局

由于任何原因导致接收到VSYNC信号的时候无法完成本次刷新操作,就会产生掉帧的现象

  • 过度绘制

在这里插入图片描述

  • 解决

    1. 去掉布局的背景色
    2. 去掉不必要控件的背景色
  • GPU渲染

在这里插入图片描述

  1. 橙色 :GUP做的任务
  2. 红色 :绘制视图的多少
  3. 浅蓝色 :绘制图片
  4. 深蓝色 :更新视图
  5. 绿色1 :布局测量
  6. 绿色2 :动画
  7. 绿色3 :输入处理
  8. 深绿色: 主线程耗时操作

Android性能 - 内存 (一)

  • Java内存

    1. 方法区:常量,类信息 <线程共享>
    2. 虚拟栈:每个方法由栈帧,存储方法信息 <线程私有,为Java方法服务>
    3. 本地栈:为本地方法服务
    4. 堆: 对象实例所在<线程共享>
    5. 程序计数器: 所执行的字节码行号指示器 <Java方法拥有,本地方法为空>
  • Java内存回收

    1. 标记清除 : 标记回收对象,清除被标记对象 <易产生大量碎片>

    2. 复制算法 :内存一分为二,一个现用,一个备用 <实际可用内存大小缩小为一半>

    3. 标记整理: 标记回收对象,整理(移动)存活对象 <避免内存碎片,避免一半内存的浪费 针对对象存活率较高的老年代>

    4. 分代收集: 根据对象的生命周期划分内存

      堆:

      ​ 新生代 ->大量对象死亡 -> 复制算法

      ​ 老年代 ->对象存活率高 -> 标记算法

  • 对象是否回收

    1. 引用计数

      引用对象,计数+1

      引用失效,计数 - 1

      缺点:不能解决相互循环引用

    2. 可达性分析

      以GCroot对象为根节点

      有可达引用链表示对象存活

  • Android内存

    • Dalvik虚拟机

      1. 加入JIT即时编译策略: 缺点①每次启动应用都要编译②运行时更耗电
    • ART虚拟机

      1. AOT编译策略,静态编译,安装程序的时候编译
      2. 改进GC过程
    • 两者混合编译

      1. 程序安装时dex不会被编译
      2. 运行时编译dex
      3. 手机充电或者空闲时进行AOT编译
    • 内存回收

      新生代->老年代->永久代

    • 共享内存

      Zygote的进程fork出来的程序进程

    • 分配和回收内存

Android性能 - 卡顿

60帧合适的显示速度,16ms内显示界面布局表示流畅画面

卡顿时候,帧率下降到30等,很明显的卡顿

卡顿的原因

  • UI线程中的耗时操作
    1. I/O读写
    2. 数据库访问
    3. 网络请求
  • 布局不合理
    1. 控件数量多
    2. 嵌套深
    3. overdraw
  • 内存异常
    1. 内存泄漏
    2. GC次数多 <那么CPU绘制时间就短>
  • 错误的异步操作
    1. 异步线程开启失误

寻找卡顿原因

  • stick mode

    检测程序中违例的情况

    1. 主线程进行I/O操作
    2. 主线程进行网络请求

    主要检测两大问题

    1. 线程策略 <线程使用不当>
    2. VM策略 <内存泄漏>

    使用

    if (IS_DEBUG && Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
        StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectAll().penaltyLog().build());
      StrictMode.setVmPolicy(new VmPolicy.Builder().detectAll().penaltyLog().build());
    }
    

    在debug模式下使用

    查看日志

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SE8gqmJd-1583565384982)(C:\Users\Primer4\Documents\学习笔记\1583505975013.png)]

Android性能 - 异步

异步不包治百病,不正确使用异步会更卡顿

线程调度

  • nice values线程优先级
    1. default UI线程
    2. background 后台线程
  • cgroups
    1. 控制和分离进程组
  • 使用
new Thread(new Runannable()).start()
  创建和销毁耗能大
  和UI线程具有相同的优先级,出现竞争
  匿名内部类持有外部引用,易内存泄漏
  缺乏线程管理
private class A extendes AysncTask<in,progress,result>{
   onPreExecute();//执行任务前
  doInBackground();//线程后台任务
  onProgressUpdate();//任务进度
  onPostExecute();//UI操作
  onCancelled();//取消异步操作
}

in 传入的参数
progress 进度
result 结果
	
	默认串行
	匿名内部类持有外部引用,内存易泄漏

Handler handler = new Handler(){
  handleMessage(msg);
};

	串行执行
	默认优先级和UI线程同级,出现竞争

IntentService

ThreadPoolExecutor

Android性能 - 瘦身

  • APK组成

    1. assets/ 静态文件
    2. lib/ os文件
    3. META-INF/ 签名信息
    4. res/ 资源文件
    5. AndroidManifest.xml 配置文件
    6. classes.dex Java字节码的产物
    7. resource.arsc 编译后的二进制资源文件
  • AS自带的 analyze APK工具

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ur9ZR9wf-1583565384984)(C:\Users\Primer4\Documents\学习笔记\1583560318784.png)]

  • 反编译工具 class shark

    https://github.com/google/android-classyshark/releases

  • 如何瘦身

  1. 移除无用代码

  2. 移除无用库,相同库

  3. 启用Proguard

    稍用,规则繁琐

  4. 缩减方法数

  5. 移除无用资源

 layout

 drawable
  1. 图片压缩

    压缩网站 https://tinypng.com/

    AndroidStudio插件:TinyPngPlugin,能够批量地压缩项目中的图片,更加方便。

  2. png转jpg

    png无损

    png体积大

  3. 使用矢量图

    xml, svg

  4. 使用webp

  5. 网络资源

  6. so文件瘦身

  7. 使用7zip进行极限压缩

Android性能 - 电量

  • 工具 Battery Historian

  • 电量优化

    1. CPU时间片

    2. 网络传输

      数据压缩

      传输方式

      请求处理

      无网避免请

    3. GPS

    合适的location provider

    及时注销监听

    模块复用

    1. wake lock 不休眠锁

    2. 传感器

Android性能 - 网络

  • 网络问题
    1. 流量消耗
    2. 电量消耗
    3. 热修复
    4. 弱网
  • 网络监控
    1. network monitor 网络请求
    2. fiddler charles 抓包
  • 优化方向 <速度,流量,成功率>
  1. gzip压缩减少传输
  2. IP直连去除DNS解析
  3. webp格式的图片
  4. 缩略图
  5. 网络缓存
  6. 弱网判断特殊处理

Android性能 - 无响应

  • 分类
    1. 触摸或按键等待
    2. 广播不能规定完成
    3. 服务不能规定完成
  • 原因
  1. 主线程阻塞
  2. IO等待
  3. 其他程序影响
  • 出发场景
  1. 输入5s未响应完毕
  2. 前台广播10s内未完毕,后台20s
  3. 前台服务20s,后台服务200s
  4. 内容提供者publish 10s

Android性能 - Bitmap

  • bitmap内存模型

    Android2.2之前GC执行,主线程暂停;

    Android2.3之后,GC并发执行

    API 10 bitmap像素数据存放在 native内存,对象在dalvik heap;

    3.0~8.0 像素和对象都在native内存;

    8.0~now 像素又移到了native,对象和像素可以同时回收,新增hardware bitmap

  • bitmap回收

2.2.3之前推荐使用bitmap.recycle()

3.0之后复用bitmap

  • bitmap的复用

  • bitmap的加载

  • 推荐使用图片加载框架glide,piccasso等处理图片

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章