IdleHandler,页面启动优化神器

简介: 随着App的开发到了某个阶段必然会遇到一个需求,那就是优化页面的启动时间。 第一个问题:有什么方法可以去统计页面的启动时间呢? adb logcat -s ActivityManager | grep "Displayed" 上面的命令行可用来进行查看。

随着App的开发到了某个阶段必然会遇到一个需求,那就是优化页面的启动时间。

第一个问题:有什么方法可以去统计页面的启动时间呢?

 

adb logcat -s ActivityManager | grep "Displayed"

上面的命令行可用来进行查看。

第二个问题:启动时间是包括了哪些流程,是如何被计算出来的呢?

App启动主要经过如下几个流程

  1. Launch the process.

  2. Initialize the objects.

  3. Create and initialize the activity.

  4. Inflate the layout.

  5. Draw your application for the first time.

最末尾的步骤5是绘制你的界面。所以完整的启动时间是要到绘制完成为止。

那么绘制界面对应的是什么时候呢?一般我们开发,最晚能被回调的是在onResume方法,那么onResume方法是在绘制之后还是之前呢?

no code no truth

 

final void handleResumeActivity(IBinder token,
            boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {
            //省略部分代码
            r = performResumeActivity(token, clearHide, reason);
            //省略部分代码            if (a.mVisibleFromClient) {                    if (!a.mWindowAdded) {
                        a.mWindowAdded = true;
                        wm.addView(decor, l);        

看上面的代码,就先放结论了。

在performResumeActivity 中进行了onResume的回调,在wm.addView 中进行了绘制,因此onResume的方法是在绘制之前,在onResume中做一些耗时操作都会影响启动时间。

下面就剥一下onResume的逻辑,绘制的有兴趣可以自己看源码。 首先performResumeActivity中会调用r.activity.performResume();

 


  public final ActivityClientRecord performResumeActivity(IBinder token,
            boolean clearHide, String reason) {
          //省略部分代码
        
            try {
                r.activity.onStateNotSaved();
                r.activity.mFragments.noteStateNotSaved();
                checkAndBlockForNetworkAccess();                if (r.pendingIntents != null) {
                    deliverNewIntents(r, r.pendingIntents);
                    r.pendingIntents = null;
                }                if (r.pendingResults != null) {
                    deliverResults(r, r.pendingResults);
                    r.pendingResults = null;
                }
                r.activity.performResume();

               //省略部分代码
               }
               }复制代码

然后在performResume中调用了 mInstrumentation.callActivityOnResume(this);

 
 final void performResume() {
       //省略部分代码
        mInstrumentation.callActivityOnResume(this);
        //省略部分代码
    }复制代码

最后在callActivityOnResume 调用了onResume

public void callActivityOnResume(Activity activity) {
        activity.mResumed = true;
        activity.onResume();
        //省略代码
    }复制代码

到了此处就算真正调用到了onResume的方法。

既然知道了onResume中做的操作会影响到启动时间,那么就有一个优化启动时间的思路了。

思路

把在onResume以及其之前的调用的但非必须的事件(如某些界面View的绘制)挪出来找一个时机(即绘制完成以后)去调用。那样启动时间自然就缩短了。但是整体做的事并没有明显变化。那么这个时机是什么呢?

IdleHandler

看下IdleHandler的源码

 /**
     * Callback interface for discovering when a thread is going to block
     * waiting for more messages.
     */
    public static interface IdleHandler {
        /**
         * Called when the message queue has run out of messages and will now
         * wait for more.  Return true to keep your idle handler active, false
         * to have it removed.  This may be called if there are still messages
         * pending in the queue, but they are all scheduled to be dispatched
         * after the current time.
         */
        boolean queueIdle();
    }

从这个源码可知道,IdleHandler即在looper里面的message处理完了的时候去调用,这不就是我们onResume调用完了以后的时机么。

来一张图说明一下,明显的IdleHandler在onResume以及performTraversals绘制之后调用 

94257ea12b9b883400adbd06f42a214ac8c68e75

由这个思路我把自己负责的页面中的一些界面的绘制逻辑挪到了IdleHandler中,由于有LoadingView时间,我把Adapter的绑定也挪出去了。看下优化前后效果图 

61bc11553a6f78be968a1b3e0ae816afa1a561d8

效果还是挺明显的。


原文发布时间为:2018-11-13

本文来自云栖社区合作伙伴“Android开发中文站 ”,了解相关信息可以关注“Android开发中文站”。

相关文章
|
8月前
|
机器学习/深度学习 人工智能 前端开发
机器学习PAI常见问题之web ui 项目启动后页面打不开如何解决
PAI(平台为智能,Platform for Artificial Intelligence)是阿里云提供的一个全面的人工智能开发平台,旨在为开发者提供机器学习、深度学习等人工智能技术的模型训练、优化和部署服务。以下是PAI平台使用中的一些常见问题及其答案汇总,帮助用户解决在使用过程中遇到的问题。
|
8月前
|
监控 JavaScript 安全
百度搜索:蓝易云【如何使用nginxWebUI图形化gui界面管理nginx】
虽然Nginx本身没有官方提供的图形化GUI界面,但使用第三方工具nginx-proxy-manager可以实现通过WebUI图形化界面来管理Nginx的反向代理规则。这样,你可以更方便地进行配置和管理,而无需手动修改Nginx配置文件。
123 0
|
3月前
|
存储 安全 数据安全/隐私保护
在阿里云快速启动Umami玩转网页分析
本文介绍了Umami的基本信息,并通过阿里云计算巢完成了Umami的快速部署,使用者不需要自己下载代码,不需要自己安装复杂的依赖,不需要了解底层技术,只需要在控制台图形界面点击几下鼠标就可以快速部署并启动Umami,非技术同学也能轻松搞定。
|
7月前
|
NoSQL Redis
WordPress懒人优化方案,有效提升网页加载速度
在WordPress商店安装并启用插件WP Fastest Cache,按照说明设置。确保服务器已安装Redis,再安装Redis Object Cache并启用,无需额外配置。这两个步骤能显著提升网站加载速度,带来流畅的浏览体验。
133 8
|
6月前
|
小程序
【亲测有效】3步实现 微信小程序内接入小程序客服,网页端客服工具与移动端小程序客服工具使用方法,使用入口,并设置当前客服状态
【亲测有效】3步实现 微信小程序内接入小程序客服,网页端客服工具与移动端小程序客服工具使用方法,使用入口,并设置当前客服状态
604 0
|
8月前
|
数据库
一款挺不错网站维护页面源码
一款挺不错网站维护页面源码,单HTML不需要数据库,上传到你的虚拟机就可以用做维护页面还不错,用处多。。
61 2
一款挺不错网站维护页面源码
|
7月前
|
前端开发 JavaScript C++
WordPress 非常漂亮滴动态时间小工具
这是一段关于WordPress动态时间小工具的分享。作者提供了小工具的JavaScript代码和使用教程。用户需要将JS文件放入网站根目录,并在WP后台的自定义HTML小工具中添加指定代码以显示动态时间效果。教程包括了CSS和HTML部分,代码实现了一个时钟动画。
36 0
|
8月前
|
Web App开发 缓存 前端开发
如何优化前端网页加载速度:最佳实践和工具推荐
本文探讨了如何通过采用最佳实践和利用先进的工具来优化前端网页加载速度。从压缩资源到使用CDN,从减少HTTP请求到利用缓存策略,我们将介绍一系列提高网页性能的技术手段。同时,我们还将推荐一些广受好评的工具,帮助开发者更轻松地实施这些优化策略。
|
XML 数据采集 测试技术
四、探索Xpath:解析Web页面的利器
四、探索Xpath:解析Web页面的利器
|
小程序
小程序酷炫3D登录页源码(泥陶态)
小程序酷炫3D登录页源码(泥陶态)
122 1