美文网首页
怎么获取页面加载完成的最佳时机?

怎么获取页面加载完成的最佳时机?

作者: wan7451 | 来源:发表于2019-03-07 22:16 被阅读0次

Android 开发页面的时候,一般的流程都是先加载页面,等页面加载完成后再执行其他后续操作。而获取页面加载完成的时机,有各种各样的方式。比如:

  1. 使用Handler延迟200毫秒加载
new Handler().postDelayed(new Runnable() {
  @Override
  public void run() {
    //加载数据
  }
},200);
  1. 监听全局布局加载
View root = findViewById(R.id.container);
root.getViewTreeObserver()
    .addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
        //加载数据
        root.getViewTreeObserver().removeOnGlobalLayoutListener(this);
    }
});
  1. view的Post方法
view.post(new Runnable() {
  @Override
  public void run() {
                
  }
});

今天无意中发现一个骚操作,使用 IdleHandler 获取页面加载完成的时机,代码很简单

@Override
protected void onResume() {
    super.onResume();
    getMainLooper().myQueue().addIdleHandler(new MessageQueue.IdleHandler() {
        @Override
        public boolean queueIdle() {
            //加载完成
            //false 执行一次,true 执行多次
            return false;
        }
    });
}

IdleHandler 即是懒惰的Handler。IdleHandler的方法执行时机是在MessageQueue中没有Message时执行,也就是主线程空闲的时候执行。熟悉Handler、Looper的同学一看源码就清楚了。

public static void loop() {
    //....
    for (;;) {
        //....
        Message msg = queue.next(); // might block
        //....
    }
}

在Looper的loop()方法中,会从消息队列中取出msg,然后再执行 msg.target.dispatchMessage(msg)。接下来重点看下MessageQueue.next()方法。

Message next() {
  //...
  // If first time idle, then get the number of idlers to run.
  // Idle handles only run if the queue is empty or if the first message
  // in the queue (possibly a barrier) is due to be handled in the future.
  if (pendingIdleHandlerCount < 0
    && (mMessages == null || now < mMessages.when)) {
    pendingIdleHandlerCount = mIdleHandlers.size();
  }
  if (pendingIdleHandlerCount <= 0) {
    // No idle handlers to run.  Loop and wait some more.
    mBlocked = true;
    continue;
  }

  if (mPendingIdleHandlers == null) {
    mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 4)];
  }
    mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers);
  }

  // Run the idle handlers.
  // We only ever reach this code block during the first iteration.
  for (int i = 0; i < pendingIdleHandlerCount; i++) {
    final IdleHandler idler = mPendingIdleHandlers[i];
    mPendingIdleHandlers[i] = null; // release the reference to the handler

    boolean keep = false;
    try {
      keep = idler.queueIdle();
    } catch (Throwable t) {
        Log.wtf(TAG, "IdleHandler threw exception", t);
    }

    if (!keep) {
    synchronized (this) {
    mIdleHandlers.remove(idler);
    }
  }
}

从上面的代码以及注释中就能看出,当Message为空的时候,系统就会执行IdleHandler 数组中的queueIdle()方法。所以说IdleHandler是在空闲的时候执行逻辑的。

那么在为什么说onResume()方法中 queueIdle() 是在布局加载完成调用的,请参考这个文章。
https://mp.weixin.qq.com/s/KpeBqIEYeOzt_frANoGuSg

相关文章

  • 怎么获取页面加载完成的最佳时机?

    Android 开发页面的时候,一般的流程都是先加载页面,等页面加载完成后再执行其他后续操作。而获取页面加载完成的...

  • jquery 获取图片高度以及hide和animate动画传参

    1、获取图片高度 首先想到的是页面加载完成之后去获取,然而页面加载时图片并没有加载完成。所以获取到的高度为0,所以...

  • 2017笔记——UIWebView高度获取

    获取两种webview的高度:静态页面和动态页面。 思路: 当需要获取静态页面的高度时,加载完成后,获取docum...

  • Vue 2

    钩子函数,表示在页面加载之后就执行代码 mounted 通过控制dom自动获取焦点 在页面加载完成之后执行代码...

  • iOS 开发小技巧

    根据返回的web 获取高度 //页面加载完成之后调用- (void)webView:(WKWebView*)web...

  • bom

    --> //1.在页面加载完成后才去获取节点window.onload =...

  • 小程序页面生命周期

    onLoad: 页面加载页面加载时触发,一个页面只会调用一次,可以在 onLoad 的参数中获取打开当前页面路径中...

  • JS延迟加载的几种方式

    JS延迟加载,也就是等页面加载完成之后再加载 JavaScript 文件。 JS延迟加载有助于提高页面加载速度。 ...

  • onload 和 onunload

    window.onload = function () {// 当页面加载完成执行// 当页面完全加载所有内容(包...

  • 页面加载完成提示

    主要说明的有两个关键的元素document.onreadystatechange和document.readySt...

网友评论

      本文标题:怎么获取页面加载完成的最佳时机?

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