Android画布多次绘制会导致闪烁

Android画布多次绘制会导致闪烁,android,android-canvas,surfaceview,flicker,Android,Android Canvas,Surfaceview,Flicker,有关此主题的关键字: CustomSurfaceView:三个不同级别的三个自定义surfaceview Canvas:lock/unlockAndPost方法(我没有使用自定义位图) 多螺纹(每个表面都是单独的螺纹) 形状(画布上的形状) 客户机/服务器(体系结构) 闪烁(这就是我在这里的原因) 我们正在开发一个客户端/服务器应用程序,我正在客户端工作。我从服务器接收到消息,其中包含有关路径(如圆、矩形、直线和其他形状)的常规数据(坐标、颜色、宽度[…])。web应用程序允许用户将这些在HTM

有关此主题的关键字:

  • CustomSurfaceView:三个不同级别的三个自定义surfaceview
  • Canvas:lock/unlockAndPost方法(我没有使用自定义位图)
  • 多螺纹(每个表面都是单独的螺纹)
  • 形状(画布上的形状)
  • 客户机/服务器(体系结构)
  • 闪烁(这就是我在这里的原因)
  • 我们正在开发一个客户端/服务器应用程序,我正在客户端工作。我从服务器接收到消息,其中包含有关路径(如圆、矩形、直线和其他形状)的常规数据(坐标、颜色、宽度[…])。web应用程序允许用户将这些在HTML5画布上绘制的数据发送到android设备,该设备接收这些消息并对其进行解析,将能够重新绘制所有形状。根据我自己在这方面的经验,我了解到控制画布上绘制的所有内容的最佳方法是将所有内容保存到缓冲区、数组、列表或类似的内容中,然后在需要时重用它(例如,可以使用旧路径显示、隐藏、移动或简单地更改画布上的内容)。在我看来,android应用程序遵循android开发和OOP范例的最佳实践,因此我不会假设错误与糟糕的架构有关。在本例中,我将在web客户端保存消息。当用户在HTML5画布上绘制时,包含形状信息的消息会完美地报告给android画布,但问题出现在:

    [示例] 考虑您绘制10个对象(10个消息),并且您想要在Web应用程序画布上只删除一个<强>对象,因此唯一的方法是清除所有的画布,并且重新绘制所有以前的“强”形状,而没有删除的形状< /强>(因此通过循环消息缓冲区重新发送给客户端9消息)。此方法非常适用于web应用程序,但会在android客户端上造成闪烁问题。所以在做了太多的实验之后,我找到了一个解决办法,使用Thread.sleep(100)(哇!100毫秒太多)来缓慢解析消息,让surfaceview线程正确读取数据(通过单例模式进行数据访问)并在画布的双缓冲区上写入数据。好吧,它既慢又难看,但它可以工作!事实上,我不喜欢这种“可怕”的解决方法,所以请帮我看看退出策略

    这是一段代码,画布从形状容器中获取数据,并在数据存在时绘制。每个容器的数据都来自服务器消息

    @Override
    public void run() {
        Canvas canvas = null;
        while (running) {
            //this is the surface's canvas
            try {
                canvas = shapesSurfaceHolder.lockCanvas();
                synchronized (shapesSurfaceHolder) {
                    if (shapesSurfaceHolder.getSurface().isValid()) {
                        if(!Parser.cmdClear){
    
                            //draw all the data present
                            canvas.drawPath(PencilData.getInstance().getPencilPath(),
                                    PencilData.getInstance().getPaint());
                            canvas.drawPath(RectData.getInstance().getRectPath(),
                                    RectData.getInstance().getPaint());
                            canvas.drawPath(CircleData.getInstance().getCirclePath(),
                                    CircleData.getInstance().getPaint());
                            canvas.drawPath(LineData.getInstance().getLinePath(),
                                    LineData.getInstance().getPaint());
                            canvas.drawText(TextData.getInstance().getText(),
                                    TextData.getInstance().getX(),
                                    TextData.getInstance().getY(),
                                    TextData.getInstance().getPaint());
    
                        } else {
                            //remove all canvas content and clear data.
                            canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
                            for (int i = 0; i < AbstractFactory.SHAPE_NUM; i++) {
                                abstracFactory.getShape(i).clearData();
                            }
                        }
                    }
                }
            } finally {
                if (canvas != null) {
                    shapesSurfaceHolder.unlockCanvasAndPost(canvas);
                }
            }
        }
    }//end_run()
    
    @覆盖
    公开募捐{
    Canvas=null;
    (跑步时){
    //这是曲面的画布
    试一试{
    canvas=shapeSurfaceHolder.lockCanvas();
    同步(ShapeSurfaceHolder){
    如果(ShapeSurfaceHolder.getSurface().isValid()){
    如果(!Parser.cmdClear){
    //绘制当前的所有数据
    canvas.drawPath(PencilData.getInstance().getPencilPath(),
    PencilData.getInstance().getPaint());
    canvas.drawPath(RectData.getInstance().getRectPath(),
    RectData.getInstance().getPaint());
    canvas.drawPath(CircleData.getInstance().getCirclePath(),
    CircleData.getInstance().getPaint());
    canvas.drawPath(LineData.getInstance().getLinePath(),
    LineData.getInstance().getPaint());
    canvas.drawText(TextData.getInstance().getText(),
    TextData.getInstance().getX(),
    TextData.getInstance().getY(),
    TextData.getInstance().getPaint());
    }否则{
    //删除所有画布内容并清除数据。
    canvas.drawColor(Color.TRANSPARENT,PorterDuff.Mode.CLEAR);
    for(int i=0;i
    我可以总结一下,显然,我的问题是画得太快

    注意:

    类似的概念:

    硬件加速已启用

    第17版

    测试