简介
联系人详情页面主要优化项:
- 布局优化
- 绘制优化
- Launch time
- 内存优化
- 卡顿优化
工具
详情页面的优化会用到下面的工具:
- HierarchyViewer检查layout布局
- Show GPU Overdraw检测Overdraw
- Android Profiler检测CPU,Memory等情况
- LeakCanary 内存泄漏检测工具
- BlockCanary/ BlockMonitor 卡顿检测工具
环境
- 设备:ZB570TL
- image: 最新image
- 联系人 500 +
- 10笔有头像
1. 渲染优化
渲染优化在前面的详情页面有详细步骤,这里不在赘述
优化
TODO
效果对比
TODO
2. Launch time
分析 和 优化
-
使用工具分析模块response time
- preview launch time:497.40 ms
- while launch time: 821.20
- application launch time: 118.20
时间统计请参看:200-2 Performance Rule - Contact.xlsx
时间是满足基本要求的
-
代码逻辑检查
- 移除TIME_BLOCK相关逻辑,新版不支援
-
查看多进程情况
判断仅主进程才进入Application的OnCreate中一些初始化
因为remote 百度定位进程不需要初始化这些数据.
-
使用MethodTrace监测
-
Application的OnCreate方法耗时细节,我们采用埋点的方式监控
可以看出除了一些监测工具的消耗,app本身的一些必要初始化消耗大都在30ms左右,算是正常消耗
-
Home页面
首页启动时间点不好掌控,因此我们采用空的Activity过渡的方式搭配CPU Profile来分析
-
系统系统方法的耗时
系统方法的耗时,可以通过渲染优化,逻辑优化,代码优化,算法优化等来优化。
如果来得及,可以先做渲染优化
-
包名过滤 com..
重点查看10%及以上的方法
- ViewUtil.isSupportVoLTE(this) 耗时126ms, 13.7%; 有跨进程的操作
- onResume中的updateViewConfiguration 耗时113,12.4%; 有数据库状态查询和等待的动作
上面两项几项均放到AsyncTask中执行
例如
class InitAsyncTask extends AsyncTask<Void, Void, Boolean> { private Reference<MainDialtactsActivity> mActivityRef; InitAsyncTask(MainDialtactsActivity activity) { mActivityRef = new WeakReference<>(activity); } @Override protected Boolean doInBackground(Void... voids) { try { return !(ViewUtil.isCMCCSku() && ViewUtil.isSupportVoLTE(mActivityRef.get().getApplicationContext())); } catch (Exception e) { Log.w(TAG, "InitAsyncTask ex", e); } return true; } @Override protected void onPostExecute(Boolean aBoolean) { if (mActivityRef == null || mActivityRef.get().isDestroyed()) { return; } View conCall = findViewById(R.id.menu_Con_call); if (aBoolean) { conCall.setVisibility(View.GONE); ...... } } }
-
-
效果对比
优化 200ms +
-
优化前
-
优化后
3. 内存优化
分析和优化
1. 接入内存泄漏工具LeakCanary
一周后,未发现明显Leak问题
2. Android Profile监测线程和Service创建情况
Android Profile监测
- 是否需要创建线程池
- AsyncTask是否需要设置并行
- Service创建的合理性
检测结果
- 有一处匿名创建Thread的情况,修改放入CacheThreadPool中
3. 动态allocation分析
Android Profile record memory查看alloc分配,分析动态allocation是否合理
(1) 应用包名过滤: com.. [alloc 59K] [Pass]
- list等都有重用
- 默认图片也都有重用
(2) 整体分析 [alloc 3.5M]
- by callstack,共13 thread,查看了200K+的thread
- main线程 [2M],100K以上消耗基本都来自布局加载
- call log query ThreadPool [758K]
- 300K+ 是来自CooTek三方库消耗
到这里可以看出非UI线程消耗基本在1.5M
- by package, 查看100K + 的集合
未发现严重的内存问题
4. memory分析内存泄漏
分析退出时的dump memory,查看是否有内存没有及时释放,避免内存泄漏
步骤
- 设置“不保留活动”
- 第一次进入页面,做一些常规操作,GC 2次后dump memory - m1,AS导出 (用作后面的MAT比较)
- 退出重新进入,重复4次,GC 2次后dump meory - m2,AS导出
AS工具分析
查看是否有多个实例存在的情况(因为我们退出/重进了多次)
按照包名排序查看,HomeActivity没有泄漏的情况,都有成功销毁
还有model这里,有四个Reference,从分析来看他们都是指向同一个实例。之所有会有这么多是因为有很多内部类持有了外类的引用
注意哈,这里有两个Application对象和两个TestLaunchActivity对象,是因为app有两个进程
分析结果:暂没有发现严重的内存泄漏
MAT分析内存泄漏
转MAT格式
hprof-conv heap-original.hprof heap-converted.hprof
我们先采用明确方式,再采用传统方式,最后做进阶分析
-
明确方式
-
传统方式
-
进阶分析
效果对比
待补充
测试重点
- 主页面加载
- 联系人列表,编辑
- call log列表,编辑