SurfaceView, onDraw and postInvalidate() something wrong

99封情书 提交于 2019-12-11 06:49:45

问题


App behave itself strangely. I have a class extends the SurfaceView and implements SurfaceHolder.Callback .
I tried 3 options of code and only one works like i need (but I'm doubt that it is a right solution) and other have different behavior.
So, my question is why and what is wrong and if "right" solution is wrong, so why it's work...

Right for all:

  1. I tried setWillNotDraw(boolean flag) flag(true/false)
  2. In manifest set android:changeConfiguration="orientation"
  3. In main layout set background with tiling picture defined via xml resources.

Now the "right" implementation: I have thread which call postInvalidate(); with delays and calls between lockCanvas and unlockCanvas:
my onDraw() and draw(Canvas c,int deg) same in all variations:

@Override
public void onDraw(Canvas c) {
    draw(c,lastHeading);
    super.onDraw(c);
}

public synchronized void draw(Canvas c,int degrees) {
    Paint p=new Paint();
    p.setAntiAlias(true);
    c.save();

    rotateLayer(degrees,layer1, cLayers.getDrawable(0),false);
    rotateLayer(lastSideAngle, layer2, sLayers.getDrawable(1),true);
    rotateLayer(lastFrontAngle, layer2, fLayers.getDrawable(1),true);

    c.drawBitmap(layer1,0, 0, p);
    c.drawBitmap(layer2,0, 0, p);
    c.drawBitmap(layer3, 0,0, p);   
    c.restore();
}

Problem code variant A (and "right" ):

@Override
public void run() {
    Canvas c=null;
    try
    {
        c=holder.lockCanvas(null);
        synchronized (holder) {
        postInvalidate();
    }
    finally
    {
        if(c!=null)
        holder.unlockCanvasAndPost(c);
    }
}

why it works without problems however same code without lock/unloc of canvas didn't work corectly?

With next implementation app work nice until phone doesn't change orientation. While changing orientation its take along time to redraw the surface, but in next orientation change it changes fast. but in both variants i call to postInvalidate() and I not understand how lock/unlock Canvas affect on postInvalidate() ?

@Override
public void run() {
    postInvalidate();
}

And in this variant I see on screen a frozen image which never cahnges:

@Override
public void run() {
    Canvas c=null;
    try
    {
        c=holder.lockCanvas(null);
        synchronized (holder) {
        draw(c,deg);
        //OR
        //onDraw(c)
    }
    finally
    {
        if(c!=null)
        holder.unlockCanvasAndPost(c);
    }
}

There is one more variant when app draws the all bitmaps but a background is overlayed its all. So what i do wrong and what i need to do?


回答1:


Here:

@Override
public void run() {
Canvas c=null;
   try
   {
       c=holder.lockCanvas(null);
       synchronized (holder) {
       draw(c,deg);
       //OR
       //onDraw(c)
   }
   finally
   {
       if(c!=null)
       holder.unlockCanvasAndPost(c);
   } 
}

You need to set up a loop, because otherwise you are calling the onDraw() method only once. This would create a continuous redrawing:

while(true) {
   try
   {
       c=holder.lockCanvas(null);
       synchronized (holder) {
       draw(c,deg);
       //OR
       //onDraw(c)
   }
   finally
   {
       if(c!=null)
       holder.unlockCanvasAndPost(c);
   } 
}

Source



来源:https://stackoverflow.com/questions/9855912/surfaceview-ondraw-and-postinvalidate-something-wrong

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!