美文网首页
性能优化的套路

性能优化的套路

作者: zsj1225 | 来源:发表于2017-08-02 10:13 被阅读52次

    1 减少过渡绘制

    1.1 怎么查看是否存在过度绘制?

    我们可以通过手机设置里面的开发者选项,打开Show GPU Overdraw的选项,可以观察UI上的Overdraw情况。



    蓝色,淡绿,淡红,深红代表了4种不同程度的Overdraw情况,我们的目标就是尽量减少红色Overdraw,看到更多的蓝色区域

    1.2 怎么解决过度绘制?

    1.2.1 移除Window默认的Background

    在onCreate方法中加入,getWindow().setBackgroundDrawable(null);

    1.2.2 移除XML布局文件中非必需的Background

    1.2.3 自定义 View 时重写 hasOverlappingRendering 方法返回false。

    该方法用来标记当前view是否存在过度绘制,存在返回ture,不存在返回false,默认返回为true。
    当继承了hasOverlappingRendering()方法返回false后,android会自动进行合理的优化,避免使用offscreen buffer。

    2 布局优化

    2.1 减少布局的嵌套层级

    可以hierarchyviewer去看布局的嵌套层级
    原则:
    1,用RelativeLayout减少嵌套的层级。
    2,同等层级情况下可以实现的选用LinearLayout而不是RelativeLayout。

    2.2 当某些UI满足某种条件才显示复杂UI就用ViewStub

    在开发过程中,经常会遇到这样一种情况,有些布局很复杂但是却很少使用。例如条目详情、进度条标识或者未读消息等,这些情况如果在一开始初始化,虽然设置可见性 View.GONE ,但是在Inflate的时候View仍然会被Inflate,仍然会创建对象,由于这些布局又想到复杂,所以会很消耗系统资源。
    ViewStub就是为了解决上面问题的,ViewStub是一个轻量级的View,它一个看不见的,不占布局位置,占用资源非常小的控件。

    2.3 有些大像素有规律的图片用.9去代替

    2.4 去掉无用的UI

    2.5 合并布局,用TextView代替图片加文字

    3 分析代码耗时情况

    可以通过traceview去分析代码的耗时情况。

    traceView虽然很牛逼。但是网上大部分文章都是浅浅说一下。
    经过这段时间不段试错,整理一个可行的套路。

    套路开始:

    3.1 生成.trace 文件

    首先肯定生成用TraceView生成.trace文件。
    生成.trace文件是方式有两种。

    3.1.1 在DDMS工具中生成

    最常用的使用方式

    1,选择到DDMS界面,选择要检测耗时的进程,比如我的就是com.android.dialer

    image.png

    2,点击采集如下图

    image.png

    会出现这样的对话框(这个就是多长时间采集一次数据),点击ok即可。

    image.png

    这时候开启采集按钮会编程停止采集的按钮(带黑色正方形)

    image.png

    3,在手机执行你检测耗时的操作。比如:我想测试最近通话和联系人Tab的切换耗时。就去手动去不断去切换Tab界面或者也可以用脚本
    4,执行完操作后,点击停止采集的按钮(带黑色正方形)停止采集,就会生成.trace文件,如下图:

    image.png

    3.1.2 在代码中用代码设置开始采集的点和停止采集的点

    比如应用的冷启动,进程还没有出现是无法选择进程的。比如界面跳转的耗时情况想精确到哪里开启采集,哪里结束采集。就需要在代码中用代码设置。

    下面以冷启动举个栗子
    1,设置开始采集点--Debug.startMethodTracing();
    在Application的onCreate()方法中写上Debug.startMethodTracing();为开始采集

    image.png

    2,设置结束采集点 -- Debug.stopMethodTracing();
    我们就在主界面显示的时候设置采集结束点,可以在onResume的末尾,也可以在onWindowFocusChanged参数出入为true的时候设置结束点。

    image.png

    3,运行代码,生成.trace文件
    那么.trace文件在哪里呢?
    只可能在两个地方。
    一就是在SD根目录

    image.png

    二就是在/sdcard/Android/data/包名/files/dmtrace.trace
    4.取出来。相信大家都会。

    注意:不采集了要把Debug.startMethodTracing();和Debug.stopMethodTracing();删掉。

    3.2 打开.trace 文件

    打开.trace文件也有两种方式:

    3.2.1 在Eclipse上打开(建议你忘记这种方式)

    为什么要忘记这种方式?
    因为这个搜索用不了。

    image.png

    如果搜索用不了,那么3.3的快速找到耗时的方法就就进行不了。但是还是能找到耗时的方法的。但是就是体力活,说得更准确一点就是眼力活,我保证看到你想哭。所以忘记这样方式吧。

    3,.2.2 用命令打开(推荐)

    1,怎么用命令打开?
    把.trace 文件拷贝到\sdk\tools这个文件夹下。

    image.png

    1.trace(因为我改名字了而已)。
    在这文件夹打开命令行输入 traceview.bat 1.trace (.trace的全名称),如下图

    image.png

    就打开了,如下图

    image.png

    用命令打开有什么好处呢?当然就是能搜索关键字啊!如下图

    image.png

    但是在DDMS工具中生成.trace 文件默认就是在Eclipse上打开的。怎么办?
    但是是找到这个DDMS生成的.trace 文件啊,但是在哪里呢?
    鼠标放在这块区域,

    image.png

    看到没有,在这路径下。

    image.png

    就在这里了。最好点击修改日期排序,第一个就你要找的文件了。

    image.png

    3.3 快速找到耗时的方法

    打开了,最重要的一步来了。这段时间的试错主要是在哪里试错,怎么快速找到耗时方法,而不是有了traceView还得用眼睛一行行去看,这是要累死人的节奏啊。

    image.png

    圈中的从左到右
    Name :该线程运行过程中所调用的函数名
    Incl Cpu Time %: 某函数占用的CPU时间,包含内部调用其它函数的CPU时间的百分比
    Incl Real Time : 某函数运行的真实时间(以毫秒为单位),内含调用其它函数所占用的真实时间
    Call+Recur Calls/Total:某函数被调用次数以及递归调用占总调用次数的百分比
    Real Time/Call: 同CPU Time/Call类似,只不过统计单位换成了真实时间

    这上面是五个列是最重要的。其他列没有什么作用,为了不受影响,我们把这个五个列放到一起。

    image.png

    这样就可以排除干扰列了,同时又有更大的空间看清楚Name列的函数名。

    然后呢?
    还记得Incl Real Time这列吗?这列就是函数的耗时时间。
    我们就让这列的耗时时间从大到小排列。
    点一下列名,就看到

    image.png

    函数的耗时时间从大到小排列了。
    这样有什么用?

    这时候就用到搜索功能了。
    举个栗子

    _u8C37_u6B4C.gif

    我就搜索com.andr(因为我的包名是com.android.dialer但是每一个类的命名都是以com.android.diaer开头的,所以我搜索了com.andr尽量搜索多一下结果,再判断是不是我程序的类)。

    输入com.andr,一个个回车,直到找到自己的类的

    image.png

    onPageScrolled这方法总耗时436ms,调用一次耗时1.857ms。
    他的函数里面方法
    getRtlPosition(position);总耗时175.106ms,占了百分之45.5
    再看代码。

    image.png

    这是viewpager的回调方法onPageScrolled,在切换的viewpager的时候会回调很多次。真的有必要在哪里判断是不是从右到左的语言吗?
    所以改成:只要在onPageSelected的方法判断就行了。这个方法在切换完成后只回调一次。

    image.png

    改完之后,运行代码。再traceView一下。对比是否改好了。
    用命令打开,优化的.trace 文件。
    搜索onPageScrolled这个优化后的代码看总耗时和每次耗时多少。

    image.png

    很明显看出来上面的没有优化前的被调用235次一共耗时436.367ms。每次调用1.857ms
    和优化后的被调用了319次才一共耗时279.367ms要小得多。每次调用1.721ms

    接下就在原来的trace文件找耗时方法了。同上。

    总结 : 就是根据Incl Real Time进行从耗时时间从长到短排序,然后搜索关键字符串,找属于自己的代码的耗时方法,优化即可

    注意:traceView写的多少ms都不等同于代码的执行的真实时间。但是是代码执行真实时间的倍数。有可能是2倍,5倍,10倍什么的,但是一定具备参考意义。

    关于这个套路和TraceView具体使用http://www.jianshu.com/p/2ef139f5dfac

    相关文章

      网友评论

          本文标题:性能优化的套路

          本文链接:https://www.haomeiwen.com/subject/ljrelxtx.html