title: Problem ending my game (UI Thread won't let me open a new Activity)
body: <p>I'm having trouble tying off my program (ending it up). I have a SurfaceView in an Activity, and in that SurfaceView when you lose three lives the game is supposed to end. I have tried opening up a new Activity but I get a keyDispatchingTimedOut error. I know it has to do with my UIThread. I have been told to create a handler in my activity and then accessible to my surfaceview. Then I can send a message to my handler and it can update the UI(or launch a new activity) in the main UI Thread. However...I have no idea how to do this! Which activity do I create the handler in? The one I want to launch the new Activity from? I'm really lost here, and this is the last piece I need to make my program cohesive. If nothing else, how could I just CLOSE the activity? My UI Thread is causing a lot of problems :(</p>
  
  <p>Surface View</p>
  
  <pre><code>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&lt;Blossom&gt; blossomVector = new Vector&lt;Blossom&gt;();
  Iterator&lt;Blossom&gt; 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();
  
  
      // 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 = "" + 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: " + 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() &gt; box_x &amp; event.getY() &gt; box_y &amp; 
                  event.getX() &lt; box_x + boxWidth &amp; event.getY() &lt; box_y + boxHeight)
          {
              mode = true;
          }
      }
  
      if(event.getAction() == MotionEvent.ACTION_MOVE) {
          if(event.getX() &gt; box_x &amp; event.getY() &gt; box_y &amp; 
                  event.getX() &lt; box_x + boxWidth &amp; event.getY() &lt; 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, "score.txt");
                  FileWriter writer = new FileWriter(highscoresFile, true);
                  BufferedWriter out = new BufferedWriter(writer);
                  //out.newLine();
                  out.append(score);
                  out.newLine();
                  out.close();
                  }
              } catch (FileNotFoundException e1) {
                  // TODO Auto-generated catch block
                  e1.printStackTrace();
              } catch (IOException e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
              }
  
  
  
  
  
          try {
              thread.join();
          } catch (InterruptedException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
          }
  
  
          }
  
      }
  }
  </code></pre>
  
  <p>}</p>
  
  <p>Thread</p>
  
  <pre><code>public class BoardThread extends Thread {
  
  private SurfaceHolder surfaceHolder;
  private BoardView boardView;
  
  private Vector&lt;Blossom&gt; blossomVector;
  private int boxX;
  private int boxY;
  private int boxWidth;
  private int boxHeight;
  private boolean mrun =false;
  private Iterator&lt;Blossom&gt; iterator;
  
  private static final String TAG = "Debug";
  
  public BoardThread(SurfaceHolder holder, BoardView boardView2, 
          Vector&lt;Blossom&gt; blossomVector1, Iterator&lt;Blossom&gt; 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);
               }
           }
       }
    }
  </code></pre>