V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
lixyz
V2EX  ›  Android

Android 遇到卡顿了,请教大神来指点

  •  
  •   lixyz · 2019-04-21 03:52:26 +08:00 · 10879 次点击
    这是一个创建于 2081 天前的主题,其中的信息可能已经有所发展或是发生改变。

    就是一个简单的页面跳转

    点击 ActivityA 当中的一个按钮,跳转到 ActivityB

    现在偶尔会发生这样的情况:在点击了 A 页面的按钮之后,但并不跳转,等待几秒之后,才会跳转

    也许有的同学会认为是在主线程当中做了什么耗时的操作

    但并没有,所有相关的数据库、网络操作都在子线程当中进行的

    我在 ActivityB 的 onCreate、onStart 和 onResume 方法打印了 log,分别计算这几个方法的执行时间

    都是几毫秒,最多是 2、30 毫秒

    最诡异的是,点击了按钮,ActivityB 当中的 log 打印,时间正常,但界面却不显示跳转,等待几秒之后才跳

    哦对了,ActivityB 当中有个自定义的 SurfaceView,因为不懂 SurfaceView,只是谷歌了一下用法自定义了一个控件,是不是这个 SurfaceView 搞的鬼?

    按说也不应该啊,当初就是因为担心卡顿才用的 SurfaceView,SurfaceView 的所有绘制都是在子线程当中进行的啊,怎么会卡顿呢?

    有没有同学了解的?求帮忙解惑!

    xiusedelang
        1
    xiusedelang  
       2019-04-21 07:33:12 +08:00 via Android
    调试工具可以看线程里函数调用流程,每个函数的具体耗时
    somebody
        2
    somebody  
       2019-04-21 08:07:05 +08:00 via Android
    systrace
    yingyue
        3
    yingyue  
       2019-04-21 08:45:36 +08:00 via Android
    surfaceview 初始化慢。卡顿应该就是这个引起的
    fffang
        4
    fffang  
       2019-04-21 11:32:43 +08:00
    注释掉 SurfaceView 看一下很难吗
    seagull007
        5
    seagull007  
       2019-04-21 11:37:07 +08:00 via iPhone
    B 页面日志打印出来证明已经执行到 b 页面的函数了,界面没显示,仅仅是没显示,执行完毕 B 页面的 onstart 方法界面才能显示出来.
    你把 surfaceview 去掉,换成普通的 textview,做一个对比,就能发现是不是 surfaceview 有问题
    cst4you
        6
    cst4you  
       2019-04-21 17:40:28 +08:00
    30 毫秒就能让一个 60 帧的描绘跳掉 1~2 帧
    lixyz
        7
    lixyz  
    OP
       2019-04-21 19:07:30 +08:00
    @cst4you @fffang @seagull007 @somebody @xiusedelang @yingyue 感谢各位
    报告一下后续

    我生成了 trace 文件分析了一下,发现是 SurfaceView 当中的 `holder.lockCanvas()`这句代码耗的时间
    但问题是这句是运行在子线程当中的

    同时还发现了一个情况是,在自定义 View 当中使用了 ValueAnimator 来生成 View 的值,在 ActivityB 的 onStart 方法中 start 了 ValueAnimator,我把这个 start 方法也改成了异步的,在整个页面获取了焦点之后再启动动画

    之后就不卡顿了(原本也是偶尔发生,不知道是不是这次修改之后还没遇到)

    以后再卡顿的时候再说吧。。。好像暂时是解决了
    somebody
        8
    somebody  
       2019-04-21 23:00:40 +08:00 via Android
    @lixyz 根据你说的内容无脑猜测:lockCanvas 看名字是获得 canvas 锁,canvas 是 ui 线程的概念,所以原因可能是 子线程长时间持有 canvas 锁,导致 ui 线程被倒挂
    lixyz
        9
    lixyz  
    OP
       2019-04-21 23:33:53 +08:00
    @somebody 不是,lockCanvas 方法返回的对象是一个 Canvas,然后在这个 Canvas 上 draw 一些东西,获取 Canvas 对象和绘制都是在子线程当中进行的

    可能是 holder 去 lock Canvas 的时候耗时比较严重吧

    不是很了解 SurfaceView,回头有空再研究研究吧
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1076 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 22:44 · PVG 06:44 · LAX 14:44 · JFK 17:44
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.