SurfaceView和Thread的问题

时间:2013-12-15 22:20:19

标签: android multithreading surfaceview

这是我在stackoverflow上的第一篇文章。作为android编程的初学者,我在使用带有内部线程类的SurfaceView时遇到了一些问题。我的目标是使用以下布局中的一些参数(通过EditText输入)实现简单摆的运动可视化:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
... >
<com.vitorlara.pendulosimples2.TestView
    android:layout_gravity="left"
    android:layout_width="0dp"
    android:layout_weight="8"
    android:layout_height="match_parent"
    android:background="@android:color/white"
    android:id="@+id/pendulumView">       
</com.vitorlara.pendulosimples2.TestView>
<LinearLayout 
   ... >

   <Button
    ... >      
    </Button>        

   <Button
     ... >      
    </Button>

    <EditText
    ... >                  
    </EditText>

    <EditText
     ... >                  
    </EditText>

    <EditText
     ...>                  
    </EditText>        
</LinearLayout>

当主布局中只有SurfaceView时,我可以在一个简单的版本中执行此操作。然而,当我试图在上面描绘的布局中做同样的事情时,没有任何事情发生,无论我尝试过什么。 MainTest和TestView类最重要的部分如下:

public class TestMain extends Activity{
public boolean isPlaying = false;
public boolean isErased = true;
public TestView testView;
public Button playButton;

@Override
public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    playButton = (Button) findViewById(R.id.playButton);
    isErased = true;
    testView = (TestView) findViewById(R.id.pendulumView);
}

// Play Button Listener
public void onPlayButtonClicked(View v){
            ...

    if(isErased == true){       
        testView.startPendulum();
            isPlaying = true;
        isErased = false;
    }
    else{
        if(isPlaying){
            testView.pendulumThread.threadIsRunning = false;    
            isPlaying = false;
        }
        else{
            testView.pendulumThread.start();
            isPlaying = true;
        }
    }
}

// Reset Button Listener
public void onResetButtonClicked(View v){
        testView.pendulumThread.threadIsRunning = false;
    isPlaying = false;
    isErased = true;
}

和TestView类:

public class TestView extends SurfaceView implements SurfaceHolder.Callback{
public PendulumThread pendulumThread;
...
private Paint ballPaint;
private Paint linePaint;
private Paint backgroundPaint;

// PendulumView's Constructor 

public TestView(Context context, AttributeSet attrs){
    super(context, attrs); 

    // listener from SurfaceHolder.Callback 

    getHolder().addCallback(this); 

    ballPaint = new Paint();
    linePaint = new Paint();
    backgroundPaint = new Paint();
}

public void pauseAnim(){
    pendulumThread.setRunning(false);
}

public void startPendulum(){
                    ...
        pendulumThread = new PendulumThread(getHolder());
        pendulumThread.start();
}

 // Drawing the elements
 public void drawPendulum(Canvas canvas, double elapsedTime){

    // Cleaning the background 
     if(canvas!=null){
        canvas.drawRect(0, 0, canvas.getWidth(), canvas.getHeight(), backgroundPaint);

        oldOmega = omega;
        omega = (float) (oldOmega + (gravity / length) * Math.sin(angle) * elapsedTime);

        oldAngle = angle;
        angle = (float) (oldAngle + omega * elapsedTime); 

        Ax = (float) (Ox - length * Math.sin(angle));
        Ay = (float) (Oy - length * Math.cos(angle));

        // Drawing the ball 
        canvas.drawCircle(Ax, Ay, ballRadius, ballPaint);

        // Drawing pendulum line
        canvas.drawLine(Ox, Oy, Ax, Ay, linePaint);
     }
 } // End of method drawPendulum

 // called when surface is first created
 @Override
 public void surfaceCreated(SurfaceHolder holder){
     pendulumThread = new PendulumThread(holder);
     pendulumThread.setRunning(true);
     pendulumThread.start(); // start the game loop thread
 } // end method surfaceCreated

 // called when the surface is destroyed
 @Override
 public void surfaceDestroyed(SurfaceHolder holder){

    // ensure that thread terminates properly
    boolean retry = true;
    pendulumThread.setRunning(false);
    while (retry){
       try{
          pendulumThread.join();
          retry = false;
       } // end try
       catch (InterruptedException e){
       } // end catch
    } // end while
 } // end method surfaceDestroyed

 // Thread subclass to control the game loop
 class PendulumThread extends Thread{
    private SurfaceHolder surfaceHolder; // for manipulating canvas
    public boolean threadIsRunning = true; // running by default

    // initializes the surface holder
    public PendulumThread(SurfaceHolder holder){
       this.surfaceHolder = holder;
    } // end constructor

    // changes running state
    public void setRunning(boolean running){
       this.threadIsRunning = running;
    } // end method setRunning

    // controls the game loop
    @Override
    public void run()
    {
       Canvas canvas = null; // used for drawing
       long previousFrameTime = System.currentTimeMillis(); 

       while (this.threadIsRunning)
       {
          try
          {
             canvas = this.surfaceHolder.lockCanvas(null);               

             // lock the surfaceHolder for drawing
             synchronized(this.surfaceHolder)
             {
                long currentTime = System.currentTimeMillis();
                double elapsedTimeMS = currentTime - previousFrameTime;
                drawPendulum(canvas, elapsedTimeMS/1000.00); // draw 
                previousFrameTime = currentTime; // update previous time
             } // end synchronized block
          } // end try
          finally
          {
             if (canvas != null) 
                surfaceHolder.unlockCanvasAndPost(canvas);
          } // end finally
       } // end while
    } // end method run
 } // end nested class CannonThread

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
        int height) 
{
}

   @Override
   protected void onSizeChanged(int w, int h, int oldw, int oldh)
   {
      super.onSizeChanged(w, h, oldw, oldh);
      backgroundPaint.setColor(android.graphics.Color.WHITE); // set background color
      startPendulum();
   } // end method onSizeChanged

}

LogCat表示该线程已启动,但没有任何反应。有什么帮助吗?

0 个答案:

没有答案