IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> addIdleHandler代码不执行 -> 正文阅读

[移动开发]addIdleHandler代码不执行

关于android启动速度的优化,相信大家都会用到IdleHandler去处理一些空闲任务,如下

 Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() {
            @Override
            public boolean queueIdle() {
            	//处理空闲任务
              return false;
            }
        });

既然是想提高启动速度,那么IdleHandler基本上都用在MainActivity的onCreate中,此时进入到app主页了,等待空闲时去提前执行一些非必要的初始化信息,或者进行预加载。

项目中之前版本的功能都是正常的,这段代码也能执行到,突然新版本这里面代码始终走不到,那么意味着里面初始化信息都将失效,启动速度优化也功亏一篑,好不容易做的功能,又被打回原形。

其实这个空闲handler代码不执行,根本原因只有一个,就是它不空闲并且很忙,没空处理你的空闲任务,那么为什么他会很忙呢?肯定是有地方在不停更新页面。虽然问题基本上可以定位在新老版本开发的需求中间,但是那么多代码,怎么去定位这个问题呢?

别急!别急!往下看!

我们知道整个app都是在loop中的死循环中的

for (;;) {
    Message msg = queue.next(); 
    if (msg == null) {
        return;
    }
    final Printer logging = me.mLogging;
    if (logging != null) {
        logging.println(">>>>> Dispatching to " + msg.target + " " +
                msg.callback + ": " + msg.what);
    }
    //省略代码。。。
    if (logging != null) {
        logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
    }
  }

方法中已经提供了log的打印,而且是成对出现的,开始和结束都会打印,由此我们可以尝试打印handler处理的日志,到底是谁在一直更新。

我们在addIdleHandler之前添加log:

Looper.myLooper().setMessageLogging(new LogPrinter(Log.ERROR, "Ajiang"));

这样上面的死循环代码的logging就不为空,打印如下所示:

E/Ajiang: >>>>> Dispatching to Handler (android.view.ViewRootImpl$ViewRootHandler) {301f6b1} android.view.ViewRootImpl$SendWindowContentChangedAccessibilityEvent@d7faa81: 0
        E/Ajiang: <<<<< Finished to Handler (android.view.ViewRootImpl$ViewRootHandler) {301f6b1} android.view.ViewRootImpl$SendWindowContentChangedAccessibilityEvent@d7faa81
E/Ajiang: >>>>> Dispatching to Handler (android.view.Choreographer$FrameHandler) {90e4ced} android.view.Choreographer$FrameDisplayEventReceiver@2d52722: 0
        E/Ajiang: <<<<< Finished to Handler (android.view.Choreographer$FrameHandler) {90e4ced} android.view.Choreographer$FrameDisplayEventReceiver@2d52722
        E/Ajiang: >>>>> Dispatching to Handler (android.view.ViewRootImpl$ViewRootHandler) {301f6b1} com.xxx.xxx.recyclerview.AutoPollRecyclerView$AutoPollTask@613a6b2: 0
        E/Ajiang: <<<<< Finished to Handler (android.view.ViewRootImpl$ViewRootHandler) {301f6b1} com.xxx.xxx.recyclerview.AutoPollRecyclerView$AutoPollTask@613a6b2
        E/Ajiang: >>>>> Dispatching to Handler (android.view.ViewRootImpl$ViewRootHandler) {301f6b1} android.view.View$SendViewScrolledAccessibilityEvent@363299b: 0
        E/Ajiang: <<<<< Finished to Handler (android.view.ViewRootImpl$ViewRootHandler) {301f6b1} android.view.View$SendViewScrolledAccessibilityEvent@363299b
        E/Ajiang: >>>>> Dispatching to Handler (android.view.Choreographer$FrameHandler) {90e4ced} android.view.Choreographer$FrameDisplayEventReceiver@2d52722: 0
        E/Ajiang: <<<<< Finished to Handler (android.view.Choreographer$FrameHandler) {90e4ced} android.view.Choreographer$FrameDisplayEventReceiver@2d52722
        E/Ajiang: >>>>> Dispatching to Handler (android.view.ViewRootImpl$ViewRootHandler) {301f6b1} com.xxx.xxx.recyclerview.AutoPollRecyclerView$AutoPollTask@613a6b2: 0
        E/Ajiang: <<<<< Finished to Handler (android.view.ViewRootImpl$ViewRootHandler) {301f6b1} com.xxx.xxx.recyclerview.AutoPollRecyclerView$AutoPollTask@613a6b2
        E/Ajiang: >>>>> Dispatching to Handler (android.view.Choreographer$FrameHandler) {90e4ced} null: 2
        E/Ajiang: <<<<< Finished to Handler (android.view.Choreographer$FrameHandler) {90e4ced} null
        E/Ajiang: >>>>> Dispatching to Handler (android.view.Choreographer$FrameHandler) {90e4ced} android.view.Choreographer$FrameDisplayEventReceiver@2d52722: 0
        E/Ajiang: <<<<< Finished to Handler (android.view.Choreographer$FrameHandler) {90e4ced} android.view.Choreographer$FrameDisplayEventReceiver@2d52722
        E/Ajiang: >>>>> Dispatching to Handler (android.view.ViewRootImpl$ViewRootHandler) {301f6b1} com.xxx.xxx.recyclerview.AutoPollRecyclerView$AutoPollTask@613a6b2: 0
        E/Ajiang: <<<<< Finished to Handler (android.view.ViewRootImpl$ViewRootHandler) {301f6b1} com.xxx.xxx.recyclerview.AutoPollRecyclerView$AutoPollTask@613a6b2
        E/Ajiang: >>>>> Dispatching to Handler (android.view.Choreographer$FrameHandler) {90e4ced} android.view.Choreographer$FrameDisplayEventReceiver@2d52722: 0
        E/Ajiang: <<<<< Finished to Handler (android.view.Choreographer$FrameHandler) {90e4ced} android.view.Choreographer$FrameDisplayEventReceiver@2d52722
        E/Ajiang: >>>>> Dispatching to Handler (android.view.ViewRootImpl$ViewRootHandler) {301f6b1} com.xxx.xxx.recyclerview.AutoPollRecyclerView$AutoPollTask@613a6b2: 0
        E/Ajiang: <<<<< Finished to Handler (android.view.ViewRootImpl$ViewRootHandler) {301f6b1} com.xxx.xxx.recyclerview.AutoPollRecyclerView$AutoPollTask@613a6b2

可以很明显的发现日志一直在循环打印,而且速度很快,很容易定位到AutoPollRecyclerView这个类有问题,于是查看发现这是个自动滚动的Recyclerview,还没到这个页面对应的tab就已经开始滚动了,所以这肯定是有问题的,改成切换到对应页面再去滚动。

本以为大功告成,于是重新跑遍代码,发现日志仍然再循环滚动。

E/Ajiang: >>>>> Dispatching to Handler (android.view.ViewRootImpl$ViewRootHandler) {f0cee21} com.xxx.xxx.ui.adapter.recommend.HomeChallengeAdapter$7$1@8020ce7: 0
        E/Ajiang: <<<<< Finished to Handler (android.view.ViewRootImpl$ViewRootHandler) {f0cee21} com.xxx.xxx.ui.adapter.recommend.HomeChallengeAdapter$7$1@8020ce7
        E/Ajiang: >>>>> Dispatching to Handler (android.view.Choreographer$FrameHandler) {a4b9c07} android.view.Choreographer$FrameDisplayEventReceiver@25c134: 0
        E/Ajiang: <<<<< Finished to Handler (android.view.Choreographer$FrameHandler) {a4b9c07} android.view.Choreographer$FrameDisplayEventReceiver@25c134
        E/Ajiang: >>>>> Dispatching to Handler (android.os.Handler) {e88c10f} null: 2
        E/Ajiang: <<<<< Finished to Handler (android.os.Handler) {e88c10f} null
        E/Ajiang: >>>>> Dispatching to Handler (android.os.Handler) {51748c6} null: 1
        E/Ajiang: <<<<< Finished to Handler (android.os.Handler) {51748c6} null
        E/Ajiang: >>>>> Dispatching to Handler (android.view.ViewRootImpl$ViewRootHandler) {f0cee21} com.xxx.xxx.ui.adapter.recommend.HomeChallengeAdapter$7$1@a781094: 0
        E/Ajiang: <<<<< Finished to Handler (android.view.ViewRootImpl$ViewRootHandler) {f0cee21} com.xxx.xxx.ui.adapter.recommend.HomeChallengeAdapter$7$1@a781094
E/Ajiang: >>>>> Dispatching to Handler (android.view.Choreographer$FrameHandler) {a4b9c07} android.view.Choreographer$FrameDisplayEventReceiver@25c134: 0
        E/Ajiang: <<<<< Finished to Handler (android.view.Choreographer$FrameHandler) {a4b9c07} android.view.Choreographer$FrameDisplayEventReceiver@25c134
        E/Ajiang: >>>>> Dispatching to Handler (android.view.ViewRootImpl$ViewRootHandler) {f0cee21} com.xxx.xxx.ui.adapter.recommend.HomeChallengeAdapter$7$1@a4573d: 0
        E/Ajiang: <<<<< Finished to Handler (android.view.ViewRootImpl$ViewRootHandler) {f0cee21} com.xxx.xxx.ui.adapter.recommend.HomeChallengeAdapter$7$1@a4573d

好家伙,竟然还有一处,定位代码

ll_challenge_content.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        ll_challenge_content.post(new Runnable() {
            public void run() {
                ll_challenge_content.requestLayout();
                bgParams.height = ll_challenge_content.getMeasuredHeight() + ScreenUtils.dp2px(55);
            }
        });

    }
});

这一直监听,一直刷,这不得忙到死么。看了下代码逻辑,其实这个地方完全没必要做监听的,后续发现这段代码的确是可以删掉的,就算不能删的话,可以换种思路做,要么加标记位,避免死循环,适当移除监听。

最后跑一遍代码,终于没有死循环的日志了,也能成功进入IdleHandler的执行代码中,启动优化也可以恢复正常了,叹了口气!

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-09-13 11:27:25  更:2022-09-13 11:28:56 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 4:39:57-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码