title: Android onResume() not being called
body: <p>for a while I have been creating a game engine that works on Android using Java. Unfortunately I have this problem where the onResume() method does't appear to be called. I am using a Thread to run everything, and when I minimise the app and then go back on the app, it just gives me a blank, black screen. But it DOES work when I turn the screen off and on again.</p>
  
  <p>The code that I am using for the activity:</p>
  
  <pre><code> package org.simplecorporation.myengine.core.android;
  
   import org.simplecorporation.myengine.core.Settings;
   import org.simplecorporation.myengine.core.android.input.AndroidInput;
   import org.simplecorporation.myengine.core.game.BaseGame;
  
   import android.app.Activity;
   import android.content.pm.ActivityInfo;
   import android.os.Bundle;
   import android.view.MotionEvent;
   import android.view.Window;
   import android.view.WindowManager;
  
   public abstract class AndroidActivity extends Activity {
  
  /* The abstract methods*/
  public abstract void activityCreated();
  public abstract void activityPaused();
  public abstract void activityResumed();
  public abstract void activityStopped();
  public abstract void activityRestarted();
  public abstract void activityDestroy();
  
  /* The android display */
  public AndroidDisplay androidDisplay;
  
  /* The onCreate method */
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      //Set the title
      this.setTitle(Settings.Window.Title);
      //Check the orientation and set it
      if (AndroidSettings.ScreenOrientation == AndroidSettings.SCREEN_ORIENTATION_PORTRAIT)
          this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
      else if (AndroidSettings.ScreenOrientation == AndroidSettings.SCREEN_ORIENTATION_LANDSCAPE)
          this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
      //Check if the activity should be fullscreen
      if (Settings.Window.Fullscreen) {
          //Get rid of the title bar
          this.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
          //Make the activity fullscreen
          this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN , WindowManager.LayoutParams.FLAG_FULLSCREEN);
      }
  }
  
  /* The onCreate method */
  protected void onCreate(BaseGame androidGame , Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      //Set the title
      this.setTitle(Settings.Window.Title);
      //Check the orientation and set it
      if (AndroidSettings.ScreenOrientation == AndroidSettings.SCREEN_ORIENTATION_PORTRAIT)
          this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
      else if (AndroidSettings.ScreenOrientation == AndroidSettings.SCREEN_ORIENTATION_LANDSCAPE)
          this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
      //Check if the activity should be fullscreen
      if (Settings.Window.Fullscreen) {
          //Get rid of the title bar
          this.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
          //Make the activity fullscreen
          this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN , WindowManager.LayoutParams.FLAG_FULLSCREEN);
      }
      //Create the display
      androidDisplay = new AndroidDisplay(this , androidGame);
      //Set the content view
      this.setContentView(androidDisplay);
      //Call the activity create method
      this.activityCreated();
  }
  
  /* Called when the activity is paused */
  public void onPause() {
      super.onPause();
      //Pause the thread
      this.androidDisplay.androidGameThread.paused = true;
      //Call the method
      this.activityPaused();
  }
  
  /* Called when the activity is resumed */
  public void onResume() {
      super.onResume();
      //Resume the thread
      this.androidDisplay.androidGameThread.paused = false;
      //Call the method
      this.activityResumed();
  }
  
  /* Called when the activity is stopped */
  public void onStop() {
      super.onStop();
      //Call the method
      this.activityStopped();
  }
  
  /* Called when the activity is restarted */
  public void onRestart() {
      super.onRestart();
      //Call the method
      this.activityRestarted();
  }
  
  /* Called when the activity is destroyed */
  public void onDestroy() {
      super.onDestroy();
      //Call the method
      this.activityDestroy();
      //Destroy
      this.finish();
  }
   }
  </code></pre>
  
  <p>The code that I am using for the thread:</p>
  
  <pre><code>package org.simplecorporation.myengine.core.android;
  
  import org.simplecorporation.myengine.core.game.BaseGame;
  import org.simplecorporation.myengine.core.input.InputManager;
  
  import android.util.Log;
  import android.view.SurfaceHolder;
  
  public class AndroidGameThread extends Thread {
  
  /* Is the thread running */
  public boolean running;
  
  /* Is the thread paused */
  public boolean paused;
  
  /* The surface holder */
  public SurfaceHolder surfaceHolder;
  
  /* The android game */
  public BaseGame androidGame;
  
  /* The constructor */
  public AndroidGameThread(SurfaceHolder surfaceHolder , BaseGame androidGame) {
      //Set running to false
      this.running = false;
      //Set paused to false
      this.paused = false;
      //Assign the surface holder
      this.surfaceHolder = surfaceHolder;
      //Assign the android game
      this.androidGame = androidGame;
  }
  
  /* The method to set the running variable */
  public void setRunning(boolean running) {
      this.running = running;
  }
  
  /* Returns whether the thread is running */
  public boolean isRunning() {
      return this.running;
  }
  
  /* The run method */
  public void run() {
      //Start the game
      this.androidGame.create();
      //Run while the variable running is true
      while (running) {
          //Check if the thread is paused
          if (! this.paused) {
              //Check the input
              InputManager.checkInput();
              //Set the game canvas to null
              AndroidStore.gameCanvas = null;
              //Try statement
              try {
                  //Set the game canvas
                  AndroidStore.gameCanvas = this.surfaceHolder.lockCanvas();
                  synchronized (this.surfaceHolder) {
                      //Update/Render the game
                      this.androidGame.tick();
                  }
              } finally {
                  //Check that the canvas isn't null
                  if (AndroidStore.gameCanvas != null) {
                      this.surfaceHolder.unlockCanvasAndPost(AndroidStore.gameCanvas);
                  }
              }
          }
      }
  }
  
  }
  </code></pre>
  
  <p>Also, to start the thread I use</p>
  
  <pre><code>import org.simplecorporation.myengine.core.Settings;
  import org.simplecorporation.myengine.core.game.BaseGame;
  import org.simplecorporation.myengine.core.input.InputManager;
  import org.simplecorporation.myengine.utils.ScreenUtils;
  
  import android.app.Activity;
  import android.graphics.Paint;
  import android.view.SurfaceHolder;
  import android.view.SurfaceView;
  
  public class AndroidDisplay extends SurfaceView implements SurfaceHolder.Callback {
  
  /* The android game */
  public BaseGame androidGame;
  
  /* The android game thread */
  public AndroidGameThread androidGameThread;
  
  /* The constructor */
  public AndroidDisplay(Activity gameActivity , BaseGame androidGame) {
      //Call the super constructor
      super(gameActivity);
  
      //Add the callback
      this.getHolder().addCallback(this);
  
      //Set the game activity in the AndroidStore
      AndroidStore.gameActivity = gameActivity;
  
      //Set the android game
      this.androidGame = androidGame;
  
      //Create the android game thread
      this.androidGameThread = new AndroidGameThread(this.getHolder(), this.androidGame);
  
      //Set the surface view focusable
      this.setFocusable(true);
  }
  
  /* Called when the surface is created */
  public void surfaceCreated(SurfaceHolder surfaceHolder) {
      //Create the input
      InputManager.create();
      //Set the size of the screen in the settings if full screen
      if (Settings.Window.Fullscreen) {
          Settings.Window.Size.Width = ScreenUtils.getScreenWidth();
          Settings.Window.Size.Height = ScreenUtils.getScreenHeight();
      } else {
          //Set the size of the screen in the settings
          Settings.Window.Size.Width = this.getWidth();
          Settings.Window.Size.Height = this.getHeight();
      }
      //Set the game resources
      AndroidStore.gameResources = this.getResources();
      //Create the game
      this.androidGame.gameCreated();
      //Create the paint object
      AndroidStore.gamePaint = new Paint();
      //Start the android game thread
      this.androidGameThread.setRunning(true);
      this.androidGameThread.start();
  }
  
  /* Called when the surface is changed */
  public void surfaceChanged(SurfaceHolder surfaceHolder , int format , int width , int height) {
      //Set the size of the screen in the settings
      Settings.Window.Size.Width = ScreenUtils.getScreenWidth();
      Settings.Window.Size.Height = ScreenUtils.getScreenHeight();
  }
  
  /* Called when the surface is destroyed */
  public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
      //Should the loop continue
      boolean retry = true;
      while(retry) {
          //Try and catch statement
          try {
              //Stop the game
              this.androidGame.gameStopped();
              //Close the game
              this.androidGame.gameClosing();
              //Join the thread
              this.androidGameThread.join();
              //Stop the while loop
              retry = false;
          } catch (InterruptedException e) {
  
          }
      }
  }
  
  }
  </code></pre>
  
  <p>To run all of this I have a class that 'extends' AndroidActvity and uses the following method:</p>
  
  <pre><code>protected void onCreate(Bundle savedInstanceState) {
      Settings.Window.Title = "MyEngine Android Tests";
      Settings.Android = true;
      Settings.Video.OpenGL = false;
      Settings.Audio.SoundEffectVolume = 10;
      AndroidSettings.ScreenOrientation = 1;
      Settings.Window.Fullscreen = true;
      this.onCreate(new FileTest() ,  savedInstanceState);
  }
  </code></pre>
  
  <p>The testing class:</p>
  
  <pre><code>import org.simplecorporation.myengine.core.Settings;
  import org.simplecorporation.myengine.core.android.AndroidActivity;
  import org.simplecorporation.myengine.core.android.AndroidSettings;
  
  import android.os.Bundle;
  import android.util.Log;
  
  public class MainActivity extends AndroidActivity {
  
  protected void onCreate(Bundle savedInstanceState) {
      Settings.Window.Title = "MyEngine Android Tests";
      Settings.Android = true;
      Settings.Video.OpenGL = false;
      Settings.Audio.SoundEffectVolume = 10;
      AndroidSettings.ScreenOrientation = 1;
      Settings.Window.Fullscreen = true;
      this.onCreate(new FileTest() ,  savedInstanceState);
  }
  
  @Override
  public void activityCreated() {
      // TODO Auto-generated method stub
  
  }
  
  @Override
  public void activityPaused() {
      // TODO Auto-generated method stub
      Log.d("HELLO", "I HAVE BEEN PAUSED");
  }
  
  @Override
  public void activityResumed() {
      // TODO Auto-generated method stub
      Log.d("HELLO", "I HAVE BEEN RESUMED");
  }
  
  @Override
  public void activityStopped() {
      // TODO Auto-generated method stub
      Log.d("HELLO", "I HAVE BEEN STOPPED");
  }
  
  @Override
  public void activityRestarted() {
      // TODO Auto-generated method stub
      Log.d("HELLO", "I HAVE BEEN RESTARTED");
  }
  
  @Override
  public void activityDestroy() {
      // TODO Auto-generated method stub
      Log.d("HELLO", "I HAVE BEEN DESTROYED");
  }
  
  }
  </code></pre>
  
  <p>FileTest:</p>
  
  <pre><code>package com.simplecorporation.myengine.android.tests;
  
  import java.util.List;
  
  import org.simplecorporation.myengine.core.Settings;
  import org.simplecorporation.myengine.core.audio.clip.AndroidAudio;
  import org.simplecorporation.myengine.core.game.BaseGame;
  import org.simplecorporation.myengine.core.game2d.entity.ImageEntity2D;
  import org.simplecorporation.myengine.core.gui.GUIButton;
  import org.simplecorporation.myengine.core.gui.GUICheckBox;
  import org.simplecorporation.myengine.core.gui.GUIRenderer;
  import org.simplecorporation.myengine.core.gui.GUIScrollBar;
  import org.simplecorporation.myengine.core.gui.GUISlider;
  import org.simplecorporation.myengine.core.gui.GUITextDisplayArea;
  import org.simplecorporation.myengine.core.gui.font.GUIFont;
  import org.simplecorporation.myengine.core.gui.font.bitmap.BitmapFont;
  import org.simplecorporation.myengine.core.image.Image;
  import org.simplecorporation.myengine.core.input.event.TouchEvent;
  import org.simplecorporation.myengine.core.render.basic.BasicRenderer;
  import org.simplecorporation.myengine.core.render.colour.Colour;
  import org.simplecorporation.myengine.utils.AndroidFileUtils;
  import org.simplecorporation.myengine.utils.ArrayUtils;
  import org.simplecorporation.myengine.utils.FileUtils;
  import org.simplecorporation.myengine.utils.font.FontUtils;
  
  import android.os.Environment;
  import android.util.Log;
  
  public class FileTest extends BaseGame {
  
  public ImageEntity2D image;
  public Colour colour;
  public GUIButton button;
  public GUICheckBox checkBox;
  public AndroidAudio audio;
  public GUIFont bitmapFont;
  public GUIScrollBar scrollBar;
  
  public GUIScrollBar verticalslider;
  public GUIScrollBar horizontalslider;
  public GUITextDisplayArea textDisplayArea;
  
  public FileTest() {
      createGame();
  }
  
  @Override
  public void gameCreated() {
      // TODO Auto-generated method stub
      image = new ImageEntity2D(new Image(R.drawable.menubutton));
      image.position.x = 200;
      image.position.y = 200;
      image.width = 200;
      image.height = 60;
      image.rotationVelocity = 1;
      colour = new Colour(0d, 0d, 0d, 1d);
      button = new GUIButton("AndroidGUIButton" , "Click Me" , new GUIRenderer(new Colour[] {
              Colour.LIGHT_BLUE , Colour.ORANGE , Colour.BLUE
      } , FontUtils.buildGUIFont("Arial" , Colour.WHITE , 46f)));
      button.position.x = 300;
      button.position.y = 200;
      button.width = 300;
      button.height = 60;
      button.visible = true;
  
      checkBox = new GUICheckBox("AndroidCheckBox" , new GUIRenderer(new Colour[] { Colour.WHITE , Colour.BLUE }));
      checkBox.position.x = 500;
      checkBox.position.y = 300;
      checkBox.width = 100;
      checkBox.height = 100;
      checkBox.visible = true;
  
      bitmapFont = new GUIFont(new BitmapFont(new Image(R.drawable.test) , 40, 16));
  
      GUIButton verticalsliderButton = new GUIButton("Button2" , "" , new GUIRenderer(new Colour[] {
              Colour.ORANGE ,
              Colour.LIGHT_BLUE ,
              Colour.BLUE
      } , FontUtils.buildGUIFont("Segoe UI" , Colour.WHITE , 20f)));
      verticalsliderButton.width = 100;
      verticalsliderButton.height = 20;
      verticalsliderButton.visible = true;
  
      verticalslider = new GUIScrollBar("Slider1" , verticalsliderButton , GUISlider.DIRECTION_VERTICAL , 1, new GUIRenderer(new Colour[] { Colour.RED }));
  
      verticalslider.visible = true;
      verticalslider.position.x = 200;
      verticalslider.position.y = 200;
      verticalslider.width = 30;
      verticalslider.height = 100;
  
      GUIButton horizontalsliderButton = new GUIButton("Button2" , "" , new GUIRenderer(new Colour[] {
              Colour.ORANGE ,
              Colour.LIGHT_BLUE ,
              Colour.BLUE
      } , FontUtils.buildGUIFont("Segoe UI" , Colour.WHITE , 20f)));
      horizontalsliderButton.width = 20;
      horizontalsliderButton.height = 100;
      horizontalsliderButton.visible = true;
  
      horizontalslider = new GUIScrollBar("Slider2" , horizontalsliderButton , GUISlider.DIRECTION_HORIZONTAL , 1, new GUIRenderer(new Colour[] { Colour.RED }));
  
      horizontalslider.visible = true;
      horizontalslider.position.x = 300;
      horizontalslider.position.y = 300;
      horizontalslider.width = 100;
      horizontalslider.height = 30;
  
      audio = new AndroidAudio(R.raw.encode , false , false);
  
      List&lt;String&gt; text = ArrayUtils.toStringList(new String[] {
              "Hello, this test application was made using MyEngine " + Settings.EngineVersion,
              "with the build " + Settings.EngineBuild + ". Below this message you should find",
              "a bitmap font:"
      });
      this.textDisplayArea = new GUITextDisplayArea("TextArea", text, FontUtils.buildGUIFont("Arial" , Colour.WHITE , 40f), Settings.Window.Size.Width);
      this.textDisplayArea.position.x = 0;
      this.textDisplayArea.position.y = 500;
      this.textDisplayArea.visible = true;
  
      AndroidFileUtils.writeToInternalStorage("hello.txt", ArrayUtils.toStringList(new String[] {
              "Hello World, From hello.txt"
      }));
      this.textDisplayArea.setText(AndroidFileUtils.readFromInternalStorage("hello.txt"));
  
      AndroidFileUtils.writeToExternalStorage("hello.txt", ArrayUtils.toStringList(new String[] {
              "Hello World, From hello.txt in an External Storage file :)"
      }));
  
      this.textDisplayArea.setText(FileUtils.read("eclipse.txt", false));
  
      Log.d("HELLO", "" + AndroidFileUtils.isExternalStorageWritable() + " " + Environment.getExternalStorageDirectory());
  }
  
  public void gameRender() {
      BasicRenderer.setColour(colour);
      BasicRenderer.renderFilledRectangle(0 , 0 , Settings.Window.Size.Width , Settings.Window.Size.Height);
      BasicRenderer.setColour(Colour.BLUE);
      BasicRenderer.renderFilledRectangle(100 , 100 , 100 , 100);
      BasicRenderer.setColour(Colour.WHITE);
      verticalslider.render();
      horizontalslider.render();
      image.render();
      button.render();
      checkBox.render();
      textDisplayArea.render();
      BasicRenderer.setColour(Colour.WHITE);
      bitmapFont.render("This is a bitmap font :)" , 10 , 700);
  }
  
  public void gameUpdate() {
      button.update();
      checkBox.update();
      image.update();
      verticalslider.update();
      horizontalslider.update();
      if (button.clicked) {
          colour = new Colour(0d , 0d , 0d , 1d);
          audio.play();
      }
      textDisplayArea.update();
  }
  
  public void onTouch(TouchEvent e) {
      this.colour = new Colour(this.colour.getR() + 0.01, this.colour.getG() + 0.01, this.colour.getB() + 0.01);
  }
  
  }
  </code></pre>
  
  <p>Many thanks in advance.</p>