title: AndEngine Sprite/Box2D Body removal crashes my program with no error/exception information?
body: <p>I am making a skateboarding game with obstacles you have to jump over using box2D and AndEngine. I am trying to make it so that when the player collides with an object, the object is removed and an explosion is placed at the objects old position, however something in the sprite removal code is freezing my program causing it to end (not even a force close message it just closes itself and goes to my home screen) and no error/exception information appears in logcat so I have no idea what is causing it! Here are some code snippets-</p>
  
  <p>when I create the sprites/boundaries I attach a JSONObject to the body containing the sprite and the type of sprite it is, and attach a similar JSONOBject to the sprite with the body and type:</p>
  
  <pre><code>/** method to construct our player (takes an x and y position)*/
  private void constructPlayer(final float pX, final float pY) {
  
  
      final Body body;
  
  
      /* construct the sprite of our player and set the animation */
      this.player = new AnimatedSprite(pX, pY, this.mSkaterTextureRegion);
      long[] frameDurations = {100, 100};
      player.animate(frameDurations, 4, 5, true);
  
  
      body = PhysicsFactory.createBoxBody(this.mPhysicsWorld, player, BodyType.DynamicBody, PLAYER_FIXTURE_DEF);
      this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(player, body, true, false));
      body.setUserData(makeUserDataForBody(PLAYER_TYPE,player));
      player.setUserData(makeUserDataForSprite(PLAYER_TYPE,body));
      this.mScene.registerTouchArea(player);
  
      //attach our player to the scene
      this.mScene.attachChild(player);
  }
  
  private JSONObject makeUserDataForBody(int type, Object sprite)
  {
      JSONObject myObject = new JSONObject();
  
      try {
          myObject.put("type", type);
          myObject.put("sprite", sprite);
      } catch (JSONException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
      }
      return myObject;
  }
  private JSONObject makeUserDataForSprite(int type, Body body)
  {
      JSONObject myObject = new JSONObject();
  
      try {
          myObject.put("body", body);
          myObject.put("type", type);
      } catch (JSONException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
      }
      return myObject;
  }
  </code></pre>
  
  <p>My code for the constructing the obstruction sprites is pretty much the same as constructing the player but I set a velocity for it to move:</p>
  
  <pre><code>private void addObstruction(final float pX, final float pY) {
  
  
      final Body body;
      final Sprite myObstruction;
  
      myObstruction = new Sprite(pX, pY, this.mCrateTextureRegion);
  
      body = PhysicsFactory.createBoxBody(this.mPhysicsWorld, myObstruction, BodyType.DynamicBody, OBJECT_FIXTURE_DEF);
  
      this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(myObstruction, body, true, true));
  
      body.setUserData(makeUserDataForBody(OBSTRUCTION_TYPE,myObstruction));
      myObstruction.setUserData(makeUserDataForSprite(OBSTRUCTION_TYPE,body));
  
      body.setLinearVelocity(-150f, 0);
      //attach our Obstruction to the scene
  
      this.mScene.attachChild(myObstruction);
  }
  </code></pre>
  
  <p>Here is the contactListener for my physics world:</p>
  
  <pre><code>this.mPhysicsWorld.setContactListener(new ContactListener() {
  
          @Override
          public void preSolve(Contact contact, Manifold oldManifold) {
  
          }
  
          @Override
          public void postSolve(Contact contact, ContactImpulse impulse) {            
          }
  
          @Override
          public void endContact(Contact contact) {
              // TODO Auto-generated method stub
  
                  Body obj1Data = contact.getFixtureA().getBody();
                  Body obj2Data = contact.getFixtureB().getBody();
  
                  JSONObject obj1UserData;
                  JSONObject obj2UserData;
                  int obj1Type = 0;
                  int obj2Type = 0;
                  if(obj1Data.getUserData()!=null)
                  {
                      obj1UserData =(JSONObject) obj1Data.getUserData();
                      try {
                      obj1Type = obj1UserData.getInt("type");
                      }catch (JSONException e) {
                          // TODO Auto-generated catch block
                          e.printStackTrace();
                      }
                  }
                  if(obj2Data.getUserData()!=null)
                  {
                      obj2UserData=(JSONObject) obj2Data.getUserData();
                      try {
                          obj2Type = obj2UserData.getInt("type");
                      } catch (JSONException e) {
                          // TODO Auto-generated catch block
                          e.printStackTrace();
                      }
                  }
                  switch (obj1Type)
                  {
                      case PLAYER_TYPE:
                      break;
                      case GRINDRAIL_TYPE:
                      if(isGrinding)
                          {
                              endGrind();
                              if(!isJumping)
                              fall(player);
                          }
                      break;
                      case GROUND_TYPE:
                      break;
                      case OBSTRUCTION_TYPE:
                      break;
  
                      case WALL_TYPE:
                          break;
  
  
                  }
  
                  switch (obj2Type)
                  {
                      case PLAYER_TYPE:
                      break;
                      case GRINDRAIL_TYPE:
                      if(isGrinding)
                          {
                              endGrind();
                              if(!isJumping)
                              fall(player);
                          }
                      break;
                      case GROUND_TYPE:
                      break;
                      case OBSTRUCTION_TYPE:
                      break;
  
                      case WALL_TYPE:
                          break;
                  }
  
  
          }
  
          @Override
          public void beginContact(Contact contact) {
  
                  Body obj1Data = contact.getFixtureA().getBody();
                  Body obj2Data = contact.getFixtureB().getBody();
  
  
                  JSONObject obj1UserData;
                  JSONObject obj2UserData;
                  int obj1Type = 0;
                  int obj2Type = 0;
                  if(obj1Data.getUserData()!=null)
                  {
                      obj1UserData =(JSONObject) obj1Data.getUserData();
                      try {
                      obj1Type = obj1UserData.getInt("type");
                      }catch (JSONException e) {
                          // TODO Auto-generated catch block
                          e.printStackTrace();
                      }
                  }
                  if(obj2Data.getUserData()!=null)
                  {
                      obj2UserData=(JSONObject) obj2Data.getUserData();
                      try {
                          obj2Type = obj2UserData.getInt("type");
                      } catch (JSONException e) {
                          // TODO Auto-generated catch block
                          e.printStackTrace();
                      }
                  }
  
  
                  //deal with things colliding with the player
                  if(obj1Type==PLAYER_TYPE)
                  {
                      playerCollisionHandler(obj2Data);
                  }
                  else if(obj2Type==PLAYER_TYPE)
                  {
                      playerCollisionHandler(obj1Data);
                  }
  
  
  
          }
      });
  </code></pre>
  
  <p>here is my playerCollisionHandler method:</p>
  
  <pre><code>private void playerCollisionHandler(Body secondBody)
  {
      JSONObject secondBodyData = null;
      if(secondBody.getUserData()!=null)
      {
          secondBodyData=(JSONObject) secondBody.getUserData();
      }
  
  
      JSONObject userdata = (JSONObject) player.getUserData();
      Body playerBody = null;
      try {
          playerBody = (Body) userdata.get("body");
      } catch (JSONException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
      }
      int objType = 0;
      try {
          if(secondBodyData!=null)
          objType = secondBodyData.getInt("type");
      } catch (JSONException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
      }
      if(objType == GROUND_TYPE)
      {
  
          if(playerBody.getLinearVelocity().y&lt;0)
          {
              /* If the sprites y velocity is negative the sprite is jumping,
               * don't reset the values!!!*/
          }
          else
          {
              if((isJumping)||(isFalling))
              {
                  //play landing sound
                  AndEngineTestActivity.this.mLandSound.play();
                  isJumping = false;
                  isFalling = false;
                  //player.setPosition(player.getX(), GROUND_LEVEL-player.getHeight());
                  //animate landing
                  player.animate(createFrameDurations(LAND_ANIM_FRAMES.length), LAND_ANIM_FRAMES, 0);
              }
              if(!rollSoundIsPlaying)
              {
                  playRollSound();
              }
          }
      }
      else if(objType == GRINDRAIL_TYPE)
      {
          Sprite grindRail=null;
          try {
              grindRail = (Sprite) secondBodyData.get("sprite");
          } catch (JSONException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
          }
          /*create a rectangle at the upper bound of the grind rail to test collision*/
          grindRailUpperBound = new Rectangle(grindRail.getX(), grindRail.getY(), mGrindRailTextureRegion.getWidth(), COLLISION_BOUNDS_PIXEL_ACCURACY);
          playerLowerBound = new Rectangle(player.getX(), player.getY()+player.getHeight(), player.getWidth(), COLLISION_BOUNDS_PIXEL_ACCURACY);
          grindRailUpperBound.setColor(1.0f, 0f, 0f,1f);
          playerLowerBound.setColor(1.0f, 1.0f, 0f,1f);
          mScene.attachChild(playerLowerBound);
          mScene.attachChild(grindRailUpperBound);
          if(grindRailUpperBound.collidesWith(playerLowerBound))
          {
              if(!isGrinding)
              {
                  mScene.detachChild(grindRailUpperBound);
                  mScene.detachChild(playerLowerBound);
                  grindPlayer(player);
              }
          }
  
          if(!isGrinding)
          {
              /* if it reaches this point and the custom rectangle bounds did not collide
               * it means the player has collided with the grind rail another way, so we hurt the player*/
              playerHitByObject();
              destroyObstruction(secondBody);
          }
      }
      else if(objType == OBSTRUCTION_TYPE)
      {
          playerHitByObject();
          destroyObstruction(secondBody);
  
      }
  }
  </code></pre>
  
  <p>and here is the destroyObtruction method which seems to be the culprit of the crashes (if i comment out my calls to destroyObstruction my code runs fine, but I'm not sure why this method is causing the crash...):</p>
  
  <pre><code>private void destroyObstruction(Body obstructionBody)
  {
      obstructionBody.setActive(false);
  
  
      try{
          JSONObject secondBodyData = null;
          if(obstructionBody.getUserData()!=null)
          {
              secondBodyData=(JSONObject) obstructionBody.getUserData();
          }
  
          explodeObstruction(((IEntity) secondBodyData.get("sprite")).getX(),((IEntity) secondBodyData.get("sprite")).getY());
  
          final PhysicsConnector obstructionPhysicsConnector = this.mPhysicsWorld.getPhysicsConnectorManager().findPhysicsConnectorByShape((IShape) secondBodyData.get("sprite"));
          this.mPhysicsWorld.unregisterPhysicsConnector(obstructionPhysicsConnector);
          this.mPhysicsWorld.destroyBody(obstructionPhysicsConnector.getBody());
  
          //this.mPhysicsWorld.destroyBody(obstructionBody);
          this.mScene.detachChild((IEntity) secondBodyData.get("sprite"));
  
      }catch(Exception e)
      {
          Log.d(TAG, "Exception:"+e);
      }
      catch(Error e)
      {
          Log.d(TAG, "Error:"+e);
      }
  }
  
  private void explodeObstruction(float pX, float pY)
  {
      PointParticleEmitter obstructionExplosion = new PointParticleEmitter(pX, pY);
      ParticleSystem ExplosionParticleSystem = new ParticleSystem(obstructionExplosion, 45, 60, 60, this.mCrateParticleTextureRegion);
  
  
      ExplosionParticleSystem.addParticleInitializer(new AlphaInitializer(1f));
      ExplosionParticleSystem.setBlendFunction(GL10.GL_SRC_ALPHA, GL10.GL_ONE);
      ExplosionParticleSystem.addParticleInitializer(new VelocityInitializer(-175, 175, -175, 175));
      ExplosionParticleSystem.addParticleInitializer(new RotationInitializer(0.0f, 360.0f));
      ExplosionParticleSystem.addParticleInitializer(new RotationInitializer(0f, -20f));
  
      ExplosionParticleSystem.addParticleModifier(new ScaleModifier(1.0f, 0.5f, 0, MAX_PARTICLE_LIFE/2));
  
      ExplosionParticleSystem.addParticleModifier(new AlphaModifier(1, 0.35f, 0, MAX_PARTICLE_LIFE));
  
      ExplosionParticleSystem.addParticleModifier(new ExpireModifier(MAX_PARTICLE_LIFE, MAX_PARTICLE_LIFE));
  
  
      this.mScene.attachChild(ExplosionParticleSystem);
  }
  </code></pre>