private class MyThread extends Thread { SurfaceHolder holder; // Initialised in ctor (acquired via getHolder()) Drawable sprite; // Initialised in ctor Rect bounds; // Initialised in ctor ... @OverrIDe public voID run() { while (true) { Canvas c = holder.lockCanvas(); synchronized (bounds) { sprite.setBounds(bounds); } sprite.draw(c); holder.unlockCanvasAndPost(c); } } /** * Periodically called from activity thread */ public voID updatePos(int dx,int dy) { synchronized (bounds) { bounds.offset(dx,dy); } }}
在模拟器中运行,我看到的是,在发生一些更新之后,图像的几个旧“副本”开始闪烁,即出现和消失.我最初假设也许我误解了Canvas的语义,并且它以某种方式保持了“层”,并且我正在将它颠倒过来.然而,我后来发现,如果我尝试以大约每200毫秒的速度更新,我只会得到这种效果.所以我的下一个最好的理论是,这可能是模拟器无法跟上并撕裂显示器的神器. (我还没有要测试的物理设备.)
这些理论中哪一个是正确的吗?
注意:我实际上并不想在实践中这样做(即绘制数百个相同内容的重叠副本).但是,我想了解为什么会这样.
环境:
> windows 7上的Eclipse 3.6.1(Helios)
> JDK 6
> AndroID SDK Tools r9
> App正在瞄准AndroID 2.3.1
切向问题:
我的run()方法本质上是LunarLander示例如何工作的精简版本(删除了所有多余的逻辑).我不太明白为什么这不会让cpu饱和,因为似乎没有什么可以阻止它以完全的毛皮运行.任何人都可以澄清这个吗?
解决方法 好吧,我以与你类似的方式屠杀了Lunar Lander,看到闪烁的我可以告诉你,你所看到的是每个Surface都有的双缓冲机制的简单人工制品.在附加到Surface的Canvas上绘制任何内容时,您将绘制到“后退”缓冲区(不可见的缓冲区).当你解锁CanvasAndPost()时,你正在交换缓冲区…当你的“后面”缓冲区成为“前面”时,你突然变得可见,反之亦然.所以你的下一帧绘图是在旧的“前”缓冲区完成的……
关键是你总是在备用帧上绘制单独的缓冲区.我想在图形架构中有一个隐含的假设,你总是要写每个像素.
理解了这一点后,我认为真正的问题是它为什么不闪烁硬件?在经历了多年的图形驱动程序研究之后,我可以猜测原因,但却犹豫不决.希望上述内容足以满足您对此渲染工艺的好奇心. 总结
以上是内存溢出为你收集整理的android – 调用Drawable.draw()时防止“闪烁”全部内容,希望文章能够帮你解决android – 调用Drawable.draw()时防止“闪烁”所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)