2011-05-10 6 views
0

액티비티에 SurfaceView가 있습니다. SurfaceView에 무언가가 발생하면 새로운 액티비티를 열려고합니다 (수명이 다되었을 때 - lives == 0). 나는 여러 가지 시도를 해봤지만 문제가 계속 발생합니다. UIThread를 먼저 중지하면 물론 계속 실행되지 않으므로 startActivity 문을 실행할 수 없습니다. 활동을 시작하면 내게 얼어 붙어서 강제로 닫습니다. 나는 믿습니다. 아무도이 문제를 겪어 본 적이 없습니까? 그렇다면이 문제를 어떻게 해결할 수 있는지 생각해보십시오. 최소한 새로운 액티비티를 열 수 없다면 어떻게 SurfaceView 내부에서 현재 액티비티를 닫을 수 있습니까?UIThread가 새로운 액티비티를 열려고 할 때 문제를 일으키고 있습니다.

public class BoardView extends SurfaceView implements SurfaceHolder.Callback{ 
Context mContext; 

// thread initialization 
private BoardThread thread; 
Thread timer; 
Thread timer2; 

// box variables 
Bitmap box = 
    (BitmapFactory.decodeResource 
      (getResources(), R.drawable.box)); 
private int box_x = 140; 
private int box_y = 378; 
private int boxWidth = box.getWidth(); 
private int boxHeight = box.getHeight(); 

// storage 
private Vector<Blossom> blossomVector = new Vector<Blossom>(); 
Iterator<Blossom> dataIterator = blossomVector.iterator(); 

// counters 
private int blossomNum = 0; 
private String score; 
private int currentScore = 0; 
private int lives = 3; 

boolean mode = false; 
boolean game = false; 

OutputStreamWriter out = null; 
FileOutputStream fOut = null; 

private static final String TAG = "Debug"; 
final Paint scorePaint = new Paint(); 

public BoardView(Context context){ 
    super(context); 

    scorePaint.setColor(Color.BLACK); 
    scorePaint.setTextSize(12); 
    scorePaint.setTypeface(Typeface.MONOSPACE); 


    //surfaceHolder provides canvas that we draw on 
    getHolder().addCallback(this); 

    //set up read/write data 
    File root = Environment.getExternalStorageDirectory(); 
    File highscoresFile = new File(root, "highscores.txt"); 


    // controls drawings 
    thread = new BoardThread(getHolder(),this, blossomVector, dataIterator, box_x, box_y, 
      boxWidth, boxHeight); 

    timer2 = new Thread(){ 
     public void run(){ 
      while(game == false){ 
       uiCallback.sendEmptyMessage(0); 
       try{ 
        Thread.sleep(5000); // change to be random 
       } 
       catch (InterruptedException e){ 
        e.printStackTrace(); 
       } 
      } 
     } 
    }; 

    timer = new Thread(){ 
     public void run(){ 
      //makes sure the player still has 3 lives left 
      while(game == false){ 
       uiCallback.sendEmptyMessage(0); 
       try { 
        Thread.sleep(2000); // wait two seconds before drawing the next flower 
       } catch (InterruptedException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } //sleep for 2 seconds 
      } 
     } 
    }; 
    timer.start(); 
    timer2.start(); 


    //intercepts touch events 
    setFocusable(true); 

} 


@Override 

public void onDraw(Canvas canvas){ 
    canvas.drawColor(Color.WHITE); 
    score = "SCORE: " + currentScore; 

    //note: pay attention to order you draw things 
    //don't change order or else blossoms will fall 
    //on top of box, not "into" it. 

    //display the scoreboard 
    canvas.drawText(score,240,420,scorePaint); 
    // uses a synchronized method to prevent concurrent modification 
    DrawBlossoms(canvas); 
    canvas.drawBitmap(box, box_x, box_y, null); 

} 

@Override 
public boolean onTouchEvent(MotionEvent event){ 
    //handles movement of box 
    if(event.getAction() == MotionEvent.ACTION_DOWN){ 
     if(event.getX() > box_x & event.getY() > box_y & 
       event.getX() < box_x + boxWidth & event.getY() < box_y + boxHeight) 
     { 
      mode = true; 
     } 
    } 

    if(event.getAction() == MotionEvent.ACTION_MOVE) { 
     if(event.getX() > box_x & event.getY() > box_y & 
       event.getX() < box_x + boxWidth & event.getY() < box_y + boxHeight) 
     { 
      mode = true; 
     } 
     if(mode == true){ 
      box_x = (int)event.getX(); 
     } 

    } 

    if(event.getAction() == MotionEvent.ACTION_UP){ 
     mode = false; 
    } 

    invalidate(); 
    return true; 
} 

@Override 
public void surfaceChanged(SurfaceHolder holder, 
     int format, int width, int height){ 
    Log.v(TAG, "Surface Changed"); 
    //somehow these don't seem to be working 
} 

@Override 
public void surfaceCreated(SurfaceHolder holder){ 
    thread.startRunning(true); 
    thread.start(); 
} 

@Override 
public void surfaceDestroyed(SurfaceHolder holder){ 
    Log.v(TAG, "Surface Destroyed"); 
    try { 
    thread.join(); 
} catch (InterruptedException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} 

} 

private Handler uiCallback = new Handler(){ 
    public synchronized void handleMessage(Message msg){ 
     //add a new blossom to the blossom Vector!! 
     blossomVector.add(new Blossom( 
      (BitmapFactory.decodeResource 
        (getResources(), R.drawable.blossom)))); 
     dataIterator = blossomVector.iterator(); 
     blossomNum++; 
     Log.v(TAG, "Number of Blossoms =" + blossomNum); 
    } 
}; 


private synchronized void DrawBlossoms(Canvas c) // method to draw flowers on screen and test for collision 
{ 
    Canvas canvas = c; 
    dataIterator = blossomVector.iterator(); 
    while (dataIterator.hasNext()) 
    { 
     Blossom tempBlossom = dataIterator.next(); 
     tempBlossom.Draw(canvas); 
     if (tempBlossom.hit(box_x,box_y, box_x + boxWidth, box_y + boxHeight, blossomVector) == true) 
     { 
      Log.v(TAG, "ITERATOR WORKS!"); 
      dataIterator.remove(); 
      currentScore += 100; 
     } 

     if (tempBlossom.dropped() == true) 
     { 
      dataIterator.remove(); 
      Log.v(TAG, "Blossom dropped"); 
      lives--; 
     } 
     if (lives == 0) 
     { 
      // stop the thread that makes blossoms 
      game = true; 
      //save the highscore 
      try { 
       File root = Environment.getExternalStorageDirectory(); 
       if(root.canWrite()){ 
       File highscoresFile = new File(root, "highscores.txt"); 
       FileWriter writer = new FileWriter(highscoresFile); 
       BufferedWriter out = new BufferedWriter(writer); 
       //out.newLine(); 
       out.write(score); 
       out.close(); 
       } 
      } catch (FileNotFoundException e1) { 
       // TODO Auto-generated catch block 
       e1.printStackTrace(); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 

      try { 
       File root = Environment.getExternalStorageDirectory(); 
       File highscoresFile = new File(root, "highscores.txt"); 
       FileReader reader = new FileReader(highscoresFile); 
       BufferedReader in = new BufferedReader(reader); 
       try { 
        String scoreTest = in.readLine(); 
        Log.v(TAG, "Score: " + scoreTest); 
        reader.close(); 

       } catch (IOException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } catch (FileNotFoundException e1) { 
       // TODO Auto-generated catch block 
       e1.printStackTrace(); 
      } 

     try { 
      thread.join(); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 


     } 

    } 
} 

은}

보드 Thread`public 클래스 BoardThread는 스레드가 {

private SurfaceHolder surfaceHolder; 
private BoardView boardView; 

private Vector<Blossom> blossomVector; 
private int boxX; 
private int boxY; 
private int boxWidth; 
private int boxHeight; 
private boolean mrun =false; 
private Iterator<Blossom> iterator; 

private static final String TAG = "Debug"; 

public BoardThread(SurfaceHolder holder, BoardView boardView2, 
     Vector<Blossom> blossomVector1, Iterator<Blossom> dataIterator, 
     int box_x, int box_y, int boxW, int boxH) { 

    surfaceHolder = holder; 
    boardView=boardView2; 

    blossomVector = blossomVector1; 
    iterator = dataIterator; 
    boxX = box_x; 
    boxY = box_y; 
    boxW = boxWidth; 
    boxH = boxHeight; 
} 

public void startRunning(boolean run) { 

    mrun=run; 
} 

@Override 
public void run() { 

    super.run(); 
    Canvas canvas; 
    while (mrun) { 
     canvas=null; 
     try { 
      canvas = surfaceHolder.lockCanvas(null); 
       synchronized (surfaceHolder) { 
       //update position 
       //Position(blossomVector, boxX, boxY, boxWidth, boxHeight); 
       // draw flowers 
       boardView.onDraw(canvas); 
      } 
     } finally { 
       if (canvas != null) { 
       surfaceHolder.unlockCanvasAndPost(canvas); 
      } 
     } 
    } 
    } 

private synchronized void Position(Vector<Blossom> blossomVector,int box_x, int box_y, 
     int boxWidth, int boxHeight) 
{ 
    //for(Blossom blossom: blossomVector) 
    iterator = blossomVector.iterator(); 
    while (iterator.hasNext()) 
    { 
     Blossom tempBlossom = iterator.next(); 
     tempBlossom.UpdatePosition(); 

    } 
} 

} 

`

답변

0

은 서피스 뷰 SurfaceView 메인 UI 스레드가 아닌 다른 스레드에서 실행되는 것처럼 소리와 수 확장 View 객체를 수정하지 마십시오. 액티비티에 Handler를 생성하고 SurfaceView에 액세스 할 수있게 할 수 있습니다. 그런 다음 핸들러에 메시지를 보낼 수 있으며 기본 UI 스레드에서 UI를 업데이트 (또는 새 활동 시작) 할 수 있습니다.

+0

Activity에서 SurfaceView에서로드 할 스레드를 만들어야한다는 말입니까? 그런 다음 SurfaceView에서 볼 메소드를 작성하십시오. 내 BoardView에서 핸들러를 액세스 가능하게 만들 수 있습니까 ?? (이것은 surfaceView 임) –

관련 문제