【Android问题及其解决】UI优化记录

UI优化记录

问题发生

实习公司的项目中,负责添加注册登录模块(原本是调用网页来实现交互的)的ui及其适配、代码编写。但是按照设计图做好ui后,点击“登录按钮”进入登录注册模块,相当耗时(2-3s),而且切换页面进行跳转的动作,也比较耗时。反复操作后,应用崩溃。

优化目标

  1. 减少页面初始化时间
  2. 流畅进行跳转。

原本的页面跳转策略+伪代码

  1. 在负责该模块的activity中,使用Handler来发送消息,在Handler的处理消息方法中进行跳转。
  2. 利用Stack来存储View,新页面先初始化,再调用一些显示前需要的调用方法,显示view,压栈。

    View view = inflate(R.layout.id,null);
    view.doSomethimgBeforeShow();
    setContentView(view);
    viewStack.push(view);
    view.doSomethingAfterShow();
    
  3. 回退

    View view = viewStack.pop();
    view.doSomethingBeforeDestroy();
    view = null;
    if(viewStack.size()>0)
        setContentView(viewStack.peek());
    else
        close();
    

寻找问题

  1. 一开始猜想是图片方面导致的内存不够,所以也做了相应的处理来回收内存,见我的上一篇博客
  2. 做了图片方面的处理后,速度稍微快了一些,但上述现象仍然很严重。于是打算使用TraceView来看看到底是什么方法,如此的耗时…

TraceView分析(真机上)

图1

在UI线程中,注意用红色框框起来和箭头所指的方法,大量的时间都被消息分发、消息处理所占用。将近两秒!我当时也有点纳闷…又没有耗时操作,只是个单纯的切换显示view,为什么用Handler呢?所以,第一个需要优化的就是避免使用Handler来进行页面跳转

模拟器上的测试也能看出来,但是有时候可能没有真机上这么明显。当cpu比较繁忙的时候,或者当前MessageQueue中消息队列很长的时候,发出一个message放到MessageQueue中可能需要很长时间才会被Looper轮询到,增加了响应时间的不稳定性。

去掉Handler来直接进行跳转后,继续使用TraceView来分析。
图2

可以看出,耗时减少了(1.5s,也没有减少多少),但是现象仍然很明显。前面的一些方法都是系统方法,挨个往下查看,注意到最后一条,是我们控制注册登录模块的activity,它的onCreate方法占用了比较多的时间,点开继续看。

图2.1

acitvity中的一个a方法(工程被混淆过)占用了onCreate()方法的99%的时间,点开继续看。

图2.2

仍然是这个a,没看出什么,继续点开这个标号17。

图2.3

这次有东西了,LoginAndroid这个类就是点击登录后第一次加载的页面,可以看到init()和inflate方法占据了绝大多数时间,点开init()方法看。

图2.4

customEditView是一个自定义控件,看耗时比例,控件的init()方法和TypeFace这个占据绝大多数时间,先不管TypeFace,点开init()。

图2.5

哎~又出现了这个TypeFace类,打开代码,发现这个类在模块中是用来获取字体资源问题,设置字体的。第二耗时的是输入框的初始化。

上面仅仅是第一个页面的初始化步骤中耗时的部分,其他页面也是一样的情况。那么问题很有可能就在这里。

将字体设置去掉后,再次在真机上调试,效果有了极大的提升,腰不酸腿不疼了。

继续

找到了问题的原因是加载字体文件过于耗时,但是字体要求又是ui上标明了的,有没有什么办法可以使用字体也能达到性能上的要求呢?

上网寻找相关资料,发现TypeFace这个类对象可以被多个对象多次使用,那这样的话,只需要初始化一次TypeFace就可以了,之后只使用这一个对象就能设置字体。所以,在全局范围内只实例化一个TypeFace即可。

最终的ui优化方案

  1. 避免使用Handler来进行页面跳转。
  2. 图片资源及时回收。
  3. 一些资源文件(例如这次的TypeFace),如果可以重复使用,那么实例化一个对象,多次调用即可。
  4. 还有一点文中没有提到,就是可以把一些在页面中不需要伴随view初始化的操作,放到其他方法中,在view初始化,显示出来后,再调用执行,就是之前伪代码中提到的

    view.doSomethingAfterShow();
    

这样页面已经显示出来了,再有一些耗时的操作,不至于会导致页面进入的时候耗时过长。

结论

  1. TraceView是神器。
  2. 很多问题在模拟器上体现不出来,真机的情况要更加复杂多变,所以这些问题也大多出现在真机测试中。只有多遇到问题+多解决问题+多总结,才能在编码过程中先见性的预防可能发生的性能问题。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值