For a while I was creating a game engine that runs on Android using Java. Unfortunately, I have this problem when the onResume () method is not displayed. I use Thread to run everything, and when I minimize the application and then return to the application, it just gives me a blank black screen. But it works when I turn off the screen again.
The code I use for the action is:
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 {
public abstract void activityCreated();
public abstract void activityPaused();
public abstract void activityResumed();
public abstract void activityStopped();
public abstract void activityRestarted();
public abstract void activityDestroy();
public AndroidDisplay androidDisplay;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setTitle(Settings.Window.Title);
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);
if (Settings.Window.Fullscreen) {
this.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN , WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
}
protected void onCreate(BaseGame androidGame , Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setTitle(Settings.Window.Title);
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);
if (Settings.Window.Fullscreen) {
this.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN , WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
androidDisplay = new AndroidDisplay(this , androidGame);
this.setContentView(androidDisplay);
this.activityCreated();
}
public void onPause() {
super.onPause();
this.androidDisplay.androidGameThread.paused = true;
this.activityPaused();
}
public void onResume() {
super.onResume();
this.androidDisplay.androidGameThread.paused = false;
this.activityResumed();
}
public void onStop() {
super.onStop();
this.activityStopped();
}
public void onRestart() {
super.onRestart();
this.activityRestarted();
}
public void onDestroy() {
super.onDestroy();
this.activityDestroy();
this.finish();
}
}
The code I use for the stream is:
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 {
public boolean running;
public boolean paused;
public SurfaceHolder surfaceHolder;
public BaseGame androidGame;
public AndroidGameThread(SurfaceHolder surfaceHolder , BaseGame androidGame) {
this.running = false;
this.paused = false;
this.surfaceHolder = surfaceHolder;
this.androidGame = androidGame;
}
public void setRunning(boolean running) {
this.running = running;
}
public boolean isRunning() {
return this.running;
}
public void run() {
this.androidGame.create();
while (running) {
if (! this.paused) {
InputManager.checkInput();
AndroidStore.gameCanvas = null;
try {
AndroidStore.gameCanvas = this.surfaceHolder.lockCanvas();
synchronized (this.surfaceHolder) {
this.androidGame.tick();
}
} finally {
if (AndroidStore.gameCanvas != null) {
this.surfaceHolder.unlockCanvasAndPost(AndroidStore.gameCanvas);
}
}
}
}
}
}
Also, to start the stream, I use
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 {
public BaseGame androidGame;
public AndroidGameThread androidGameThread;
public AndroidDisplay(Activity gameActivity , BaseGame androidGame) {
super(gameActivity);
this.getHolder().addCallback(this);
AndroidStore.gameActivity = gameActivity;
this.androidGame = androidGame;
this.androidGameThread = new AndroidGameThread(this.getHolder(), this.androidGame);
this.setFocusable(true);
}
public void surfaceCreated(SurfaceHolder surfaceHolder) {
InputManager.create();
if (Settings.Window.Fullscreen) {
Settings.Window.Size.Width = ScreenUtils.getScreenWidth();
Settings.Window.Size.Height = ScreenUtils.getScreenHeight();
} else {
Settings.Window.Size.Width = this.getWidth();
Settings.Window.Size.Height = this.getHeight();
}
AndroidStore.gameResources = this.getResources();
this.androidGame.gameCreated();
AndroidStore.gamePaint = new Paint();
this.androidGameThread.setRunning(true);
this.androidGameThread.start();
}
public void surfaceChanged(SurfaceHolder surfaceHolder , int format , int width , int height) {
Settings.Window.Size.Width = ScreenUtils.getScreenWidth();
Settings.Window.Size.Height = ScreenUtils.getScreenHeight();
}
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
boolean retry = true;
while(retry) {
try {
this.androidGame.gameStopped();
this.androidGame.gameClosing();
this.androidGameThread.join();
retry = false;
} catch (InterruptedException e) {
}
}
}
}
To run all this, I have a class that extends AndroidActvity and uses the following method:
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);
}
Testing Class:
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() {
}
@Override
public void activityPaused() {
Log.d("HELLO", "I HAVE BEEN PAUSED");
}
@Override
public void activityResumed() {
Log.d("HELLO", "I HAVE BEEN RESUMED");
}
@Override
public void activityStopped() {
Log.d("HELLO", "I HAVE BEEN STOPPED");
}
@Override
public void activityRestarted() {
Log.d("HELLO", "I HAVE BEEN RESTARTED");
}
@Override
public void activityDestroy() {
Log.d("HELLO", "I HAVE BEEN DESTROYED");
}
}
FileTest:
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() {
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<String> 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);
}
}
Thank you very much in advance.