IdleHandler,页面启动优化神器

栏目: IOS · Android · 发布时间: 7年前

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

随着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绘制之后调用 IdleHandler,页面启动优化神器

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

参考资料


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

精通正则表达式

精通正则表达式

Jeffrey E. F. Friedl / 余晟 / 电子工业出版社 / 2007 / 75

随着互联网的迅速发展,几乎所有工具软件和程序语言都支持的正则表达式也变得越来越强大和易于使用。本书是讲解正则表达式的经典之作。本书主要讲解了正则表达式的特性和流派、匹配原理、优化原则、实用诀窍以及调校措施,并详细介绍了正则表达式在Perl、Java、.NET、PHP中的用法。 本书自第1 版开始着力于教会读者“以正则表达式来思考”,来让读者真正“精通”正则表达式。该版对PHP的相关内容、Ja......一起来看看 《精通正则表达式》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码