lockCanvas()真的很慢

时间:2011-02-23 23:38:58

标签: android surfaceview frame-rate performance

在较慢的设备上测试我的游戏(橙色旧金山又名中兴Blade),我的帧速率令人震惊。

我将一些调试代码放入绘制循环中,发现以下行占用了100多天:

c = mSurfaceHolder.lockCanvas();

其他人看到过这种行为?我通过扩展View并实现onDraw()来暂时替换了surfaceview,并且我得到了很多更好的帧速率。

虽然一般来说,SurfaceView在我的HTC Desire上要快得多。我怀疑这可能是Android 2.1问题。如果可能的话,我正在考虑生根并将其升级到2.2,但我确实希望在2.1上运行一个设备,这样从长远来看可能会适得其反。

**更新**

我一直在研究这个问题,并且发现了一些令人费解的方面。

我根据手机安装了2.2并且问题仍然存在。当应用程序首次启动时,lockCanvas按预期工作(0-1毫秒)。然后在初始化期间的某个时刻,lockCanvas突然开始大约需要100毫秒。

值得指出的是,我正在异步任务中加载资源,以便显示加载屏幕。

尽管我尽力确定程序在发生缓慢时实际正在做什么,但我无法做到这一点。事实上,当我在调试模式和单步中运行它时,它运行得很快!

现在我发现如果我在SurfaceView的构造函数中添加延迟(大约10秒),则不会发生缓慢而且一切正常。

但是,如果按Home键然后再切换回来,则会缓慢回来。

对于这个愚蠢的不合逻辑的问题,我几乎已经到了最后!我有心思把它归结为设备特定的问题。

我觉得它可能与内存使用有关。也许某些东西被换掉了,它会影响视频内存?

至少我会对理论感兴趣。

4 个答案:

答案 0 :(得分:11)

关于来自docs的lockCanvas():

  

如果你反复打电话给   表面尚未准备好(之前   Callback.surfaceCreated或之后   Callback.surfaceDestroyed),你的电话   将被限制在一个缓慢的速度   为了避免消耗CPU。

对于某些设备,您的绘制循环是否可能过早启动?我认为这是问题,因为你写道:

  

现在我发现如果我添加延迟   在我的SurfaceView的构造函数中   (约10秒),缓慢   没有发生,一切正常。

答案 1 :(得分:0)

那么,也许我们可以使用holder.isCreating()来检查状态? 如果canvas仍在创建,则此方法将返回true。

喜欢的东西 while(holder.isCreating()){} 能= holder.lockCanvas();

但我现在有点困惑。我知道在创建surfaceview时会调用colbeck。我们应该实现SurfaceHolder.Callback接口。并且当表面创建回调方法时 将调用public void surfaceCreated(SurfaceHolder holder){}。 从surfaceCreated方法我开始游戏循环线程。

答案 2 :(得分:0)

我最近发现,如果使用大型位图在画布上绘制这些位图存储在活动类中 - “_surfaceHolder.lockCanvas()”命令本身需要很长时间(约70ms取决于设备)。但是,将这些位图存储移动到其他类(在不同的文件中,比如MY_DATA),并且活动只是对该新类的引用 - 解决了这个问题。

我对这种现象没有任何解释。

答案 3 :(得分:0)

我遇到了与Canvas绘图相同的神秘问题,但通过将Canvas绘图更改为绘制SurfaceView来解决它。但现在我不断放慢lockCanvas()电话。 这是我的观察结果。 问题仅存在于某些设备上:

  • Galaxy Note 3 n900:有问题
  • Galaxy Note 3 n9005:有问题
  • Galaxy S4 i9505:有问题
  • Galaxy Gio:没问题
  • LG G2 D802:有问题
  • Galaxy S2 i9100:没问题
  

我通过扩展View并实现onDraw()暂时替换了surfaceview,并且我获得了更好的帧率

我还注意到,三星手机使用GLES20Canvas代替普通Canvas并使用onDraw()绘图,因此效果更佳。