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

2019-04-21 03:52:26 +08:00
 lixyz

就是一个简单的页面跳转

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

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

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

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

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

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

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

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

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

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

6222 次点击
所在节点    Android
9 条回复
xiusedelang
2019-04-21 07:33:12 +08:00
调试工具可以看线程里函数调用流程,每个函数的具体耗时
somebody
2019-04-21 08:07:05 +08:00
systrace
yingyue
2019-04-21 08:45:36 +08:00
surfaceview 初始化慢。卡顿应该就是这个引起的
fffang
2019-04-21 11:32:43 +08:00
注释掉 SurfaceView 看一下很难吗
seagull007
2019-04-21 11:37:07 +08:00
B 页面日志打印出来证明已经执行到 b 页面的函数了,界面没显示,仅仅是没显示,执行完毕 B 页面的 onstart 方法界面才能显示出来.
你把 surfaceview 去掉,换成普通的 textview,做一个对比,就能发现是不是 surfaceview 有问题
cst4you
2019-04-21 17:40:28 +08:00
30 毫秒就能让一个 60 帧的描绘跳掉 1~2 帧
lixyz
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
2019-04-21 23:00:40 +08:00
@lixyz 根据你说的内容无脑猜测:lockCanvas 看名字是获得 canvas 锁,canvas 是 ui 线程的概念,所以原因可能是 子线程长时间持有 canvas 锁,导致 ui 线程被倒挂
lixyz
2019-04-21 23:33:53 +08:00
@somebody 不是,lockCanvas 方法返回的对象是一个 Canvas,然后在这个 Canvas 上 draw 一些东西,获取 Canvas 对象和绘制都是在子线程当中进行的

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

不是很了解 SurfaceView,回头有空再研究研究吧

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/557162

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX