title: Android - "thread exiting with uncaught exception (group=0x40015560)"
body: <p>This problem seemingly appeared from nowhere, and it's been turning me insane for the past two and half hours. I've been all around the internet, looking for a solution, but my quest was in vain.</p>
  
  <p>I've therefore decided to ask for help.</p>
  
  <p>My Android game compiles fine, and it used to run fine, but now it doesn't. <strong>It occurred at about the time when I started adding in a few more images for use in the game.</strong> </p>
  
  <p>The logged message:</p>
  
  <pre><code>01-28 20:42:34.510: WARN/dalvikvm(3857): threadid=10: thread exiting with uncaught exception (group=0x40015560)
  01-28 20:42:34.510: ERROR/AndroidRuntime(3857): FATAL EXCEPTION: Thread-11
  01-28 20:42:34.510: ERROR/AndroidRuntime(3857): java.lang.NullPointerException
  01-28 20:42:34.510: ERROR/AndroidRuntime(3857):     at com.ballbounce.bounce.MainGamePanel.update(MainGamePanel.java:153)
  01-28 20:42:34.510: ERROR/AndroidRuntime(3857):     at com.ballbounce.bounce.MainThread.run(MainThread.java:91)
  01-28 20:42:34.510: WARN/ActivityManager(105):   Force finishing activity com.ballbounce.bounce/.BallBounceActivity
  </code></pre>
  
  <p>I think the NullPointerException happens as a result of the thread exiting, not the actual <strong>cause</strong> of the thread closing, though.</p>
  
  <p>I've tried 'cleaning' the project in Eclipse, restarting Eclipse, restarting the phone... all of the usual stuff. My 'undo' function doesn't let me go back far enough to get the game to a stable state.</p>
  
  <p>Relevant code (I've tried to trim as much of it down as possible):</p>
  
  <p>BallBounceActivity.java</p>
  
  <pre><code>public class BallBounceActivity extends Activity {
      // Trimmed down for ease-of-viewing
  
      @Override
      public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
  
          requestWindowFeature(Window.FEATURE_NO_TITLE);
  
          getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
  
          sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
          sensor = sensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER).get(0);
  
          mainGamePanel = new MainGamePanel(this);
  
  
          setContentView(mainGamePanel);
  
          PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
          wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "BallBounceActivity");
      }
  
      protected void onPause() {
          // Trimmed down for ease-of-viewing
      }
  
      protected void onResume() {
          // Trimmed down for ease-of-viewing
      }
  
      protected void onStop() {
          // Trimmed down for ease-of-viewing
      }
  
      private SensorEventListener accelerationListener = new SensorEventListener() {  
          public void onAccuracyChanged(Sensor sensor, int acc) {
          }
  
          @Override
          public void onSensorChanged(SensorEvent event) {
              // Trimmed down for ease-of-viewing
          }
  
      };
  }
  </code></pre>
  
  <p>MainGamePanel.java</p>
  
  <pre><code>public class MainGamePanel extends SurfaceView implements SurfaceHolder.Callback {
      // Trimmed down for ease-of-viewing
  
      private MainThread thread;
  
      // The Fps to be displayed
      private String avgFps;
      public void setAvgFps(String avgFps) {
          this.avgFps = avgFps;
      }
  
      public MainGamePanel(Context context) {
          super(context);
  
          getHolder().addCallback(this);
  
          setFocusable(true);
  
      }
  
      @Override
      public void surfaceChanged(SurfaceHolder holder, int format, int width,
              int height) {
      }
  
      @Override
      public void surfaceCreated(SurfaceHolder holder) {
          thread = new MainThread(getHolder(), this);
  
          thread.setRunning(true);
          thread.start();
  
          random = new Random();
  
          bmpFactoryOptions = new BitmapFactory.Options();
          bmpFactoryOptions.inScaled = false;
  
          powerups = new Bitmap[12];
  
          // Copy and paste time!
          powerups[0] = BitmapFactory.decodeResource(getResources(), R.drawable.coin, bmpFactoryOptions);
          powerups[1] = BitmapFactory.decodeResource(getResources(), R.drawable.powerup_8, bmpFactoryOptions);
          powerups[2] = BitmapFactory.decodeResource(getResources(), R.drawable.powerup_9, bmpFactoryOptions);
          // Trimmed down for ease-of-viewing
  
  
          ballImages = new Bitmap[8];
  
          // Copy and paste time!
  
          ballImages[0] = BitmapFactory.decodeResource(getResources(), R.drawable.ball_0, bmpFactoryOptions);
          ballImages[1] = BitmapFactory.decodeResource(getResources(), R.drawable.ball_1, bmpFactoryOptions);
          ballImages[2] = BitmapFactory.decodeResource(getResources(), R.drawable.ball_2, bmpFactoryOptions);
          // Trimmed down for ease-of-viewing
  
          items = new ArrayList&lt;Item&gt;();
  
          theBall = new Ball(this.getWidth(), this.getHeight(), 24.0f, items, ballImages);
          platform = new Platform(this.getWidth(), this.getHeight(), 180.0f);
          player = new Player(theBall, platform);
  
          theBall.setPlayer(player);
          theBall.setPlatform(platform);
  
          x = y = 0.0f;
      }
  
      @Override
      public void surfaceDestroyed(SurfaceHolder holder) {
          // Trimmed down for ease-of-viewing
      }
  
      @Override
      public boolean onTouchEvent(MotionEvent event) {
          // Trimmed down for ease-of-viewing
      }
      public void render(Canvas canvas) {
          // Trimmed down for ease-of-viewing
      }
  
      public void update() {
          // Trimmed down for ease-of-viewing
  
          theBall.update(x, y);
          platform.update();
      }
  
      public void updateAccelerometerValues(float x, float y, float z) {
          // Trimmed down for ease-of-viewing
      }
  
      public void displayScore(Canvas canvas) {
          // Trimmed down for ease-of-viewing
      }
  
      public void displayFps(Canvas canvas, String fps) {
          // Trimmed down for ease-of-viewing
      }
  
  }
  </code></pre>
  
  <p>MainThread.java</p>
  
  <pre><code>public class MainThread extends Thread {
      // Trimmed down for ease-of-viewing
  
      public MainThread(SurfaceHolder surfaceHolder, MainGamePanel gamePanel) {
          super();
          this.surfaceHolder = surfaceHolder;
          this.gamePanel = gamePanel;
      }
  
      @Override
      public void run() {
          Canvas canvas;
          // Trimmed down for ease-of-viewing
  
          sleepTime = 0;
  
          while (running) {
              canvas = null;
  
              try {
                  canvas = this.surfaceHolder.lockCanvas();
                  synchronized (surfaceHolder) {
                      beginTime = System.currentTimeMillis();
                      framesSkipped = 0;  
  
                      this.gamePanel.update();
  
                      this.gamePanel.render(canvas);              
  
                      timeDiff = System.currentTimeMillis() - beginTime;
  
                      sleepTime = (int)(FRAME_PERIOD - timeDiff);
  
                      if (sleepTime &gt; 0) {
                          try {
                              Thread.sleep(sleepTime);    
                          } catch (InterruptedException e) {}
                      }
  
                      while (sleepTime &lt; 0 &amp;&amp; framesSkipped &lt; MAX_FRAME_SKIPS) {
                          this.gamePanel.update(); 
                          sleepTime += FRAME_PERIOD;  
                          framesSkipped++;
                      }
  
                      // Trimmed down for ease-of-viewing
                  }
              } finally { 
                  if (canvas != null) {
                      surfaceHolder.unlockCanvasAndPost(canvas);
                  }
          }
          Log.d(TAG, "Thread exited");
      }
  }
  </code></pre>
  
  <p>R.java</p>
  
  <pre><code>public final class R {
      public static final class attr {
      }
      public static final class drawable {
          public static final int ball_0=0x7f020000;
          public static final int ball_1=0x7f020001;
          public static final int ball_2=0x7f020002;
          public static final int ball_3=0x7f020003;
          public static final int ball_4=0x7f020004;
          public static final int ball_5=0x7f020005;
          public static final int ball_6=0x7f020006;
          public static final int ball_7=0x7f020007;
          public static final int coin=0x7f020008;
          public static final int ic_launcher=0x7f020009;
          public static final int powerup_8=0x7f02000a;
          public static final int powerup_9=0x7f02000b;
          public static final int powerup_9_save=0x7f02000c;
      }
      public static final class layout {
          public static final int main=0x7f030000;
      }
      public static final class string {
          public static final int app_name=0x7f040001;
          public static final int hello=0x7f040000;
      }
  }
  </code></pre>
  
  <p>Any ideas as to how to fix this problem, or even any suggestions as for how this happened, would be greatly appreciated.</p>
  
  <p>Many thanks in advance, Will.</p>