Android: Fixed app lifecycle. If you leave your activity with the back key the app will be destroyed, if you use the home key the app gets frozen in the background. You can return to it and it will be in the same state as when you left it.

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7522 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
3.0
kim..ng 14 years ago
parent 8b8e84ac6a
commit f93b95b3a4
  1. 51
      engine/src/android/com/jme3/app/AndroidHarness.java
  2. 18
      engine/src/android/com/jme3/renderer/android/OGLESRenderer.java
  3. 37
      engine/src/android/com/jme3/renderer/android/OGLESShaderRenderer.java
  4. 34
      engine/src/android/com/jme3/system/android/OGLESContext.java

@ -18,8 +18,9 @@ import com.jme3.system.android.OGLESContext;
/** /**
* * <code>AndroidHarness</code> wraps a jme application object and runs it on Android
* @author Kirill * @author Kirill
* @author larynx
*/ */
public class AndroidHarness extends Activity implements DialogInterface.OnClickListener public class AndroidHarness extends Activity implements DialogInterface.OnClickListener
{ {
@ -31,6 +32,8 @@ public class AndroidHarness extends Activity implements DialogInterface.OnClickL
protected String appClass = "jme3test.android.Test"; protected String appClass = "jme3test.android.Test";
protected Application app = null; protected Application app = null;
protected boolean debug = false;
@Override @Override
public void onCreate(Bundle savedInstanceState) public void onCreate(Bundle savedInstanceState)
{ {
@ -58,30 +61,59 @@ public class AndroidHarness extends Activity implements DialogInterface.OnClickL
app.setSettings(settings); app.setSettings(settings);
app.start(); app.start();
ctx = (OGLESContext) app.getContext(); ctx = (OGLESContext) app.getContext();
if (debug)
{
view = ctx.createView(input, GLSurfaceView.DEBUG_CHECK_GL_ERROR | GLSurfaceView.DEBUG_LOG_GL_CALLS);
}
else
{
view = ctx.createView(input); view = ctx.createView(input);
}
setContentView(view); setContentView(view);
} }
@Override
protected void onRestart(){
super.onRestart();
app.restart();
logger.info("onRestart");
}
@Override
protected void onStart(){
super.onStart();
logger.info("onStart");
}
@Override @Override
protected void onResume() { protected void onResume() {
super.onResume(); super.onResume();
view.onResume(); view.onResume();
logger.info("onResume");
} }
@Override @Override
protected void onPause() { protected void onPause() {
super.onPause(); super.onPause();
view.onPause(); view.onPause();
logger.info("onPause");
} }
// @Override @Override
// protected void onDestroy(){ protected void onStop(){
// super.onDestroy(); super.onStop();
logger.info("onStop");
}
// Debug.stopMethodTracing(); @Override
// } protected void onDestroy(){
super.onDestroy();
app.stop();
logger.info("onDestroy");
}
/** /**
@ -101,7 +133,12 @@ public class AndroidHarness extends Activity implements DialogInterface.OnClickL
s += ste.getClassName() + "." + ste.getMethodName() + "(" + + ste.getLineNumber() + ") "; s += ste.getClassName() + "." + ste.getMethodName() + "(" + + ste.getLineNumber() + ") ";
} }
} }
final String sTrace = s; final String sTrace = s;
logger.severe(t != null ? t.toString() : "Failed");
logger.severe((errorMsg != null ? errorMsg + ": " : "") + sTrace);
this.runOnUiThread(new Runnable() { this.runOnUiThread(new Runnable() {
@Override @Override
public void run() public void run()

@ -988,4 +988,22 @@ public final class OGLESRenderer implements Renderer {
} }
} }
@Override
public void invalidateState() {
// TODO Auto-generated method stub
}
@Override
public void deleteImage(Image image) {
// TODO Auto-generated method stub
}
@Override
public void setAlphaToCoverage(boolean value) {
// TODO Auto-generated method stub
}
} }

@ -32,6 +32,7 @@
package com.jme3.renderer.android; package com.jme3.renderer.android;
import com.jme3.asset.TextureKey;
import com.jme3.light.LightList; import com.jme3.light.LightList;
import com.jme3.material.RenderState; import com.jme3.material.RenderState;
import com.jme3.math.ColorRGBA; import com.jme3.math.ColorRGBA;
@ -57,6 +58,7 @@ import com.jme3.shader.Shader;
import com.jme3.shader.Shader.ShaderSource; import com.jme3.shader.Shader.ShaderSource;
import com.jme3.shader.Shader.ShaderType; import com.jme3.shader.Shader.ShaderType;
import com.jme3.shader.Uniform; import com.jme3.shader.Uniform;
import com.jme3.system.JmeSystem;
import com.jme3.texture.FrameBuffer; import com.jme3.texture.FrameBuffer;
import com.jme3.texture.FrameBuffer.RenderBuffer; import com.jme3.texture.FrameBuffer.RenderBuffer;
import com.jme3.texture.Image; import com.jme3.texture.Image;
@ -77,6 +79,8 @@ import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.microedition.khronos.opengles.GL10; import javax.microedition.khronos.opengles.GL10;
import android.graphics.Bitmap;
import android.opengl.GLES10; import android.opengl.GLES10;
import android.opengl.GLES11; import android.opengl.GLES11;
import android.opengl.GLES20; import android.opengl.GLES20;
@ -407,7 +411,11 @@ public class OGLESShaderRenderer implements Renderer {
logger.log(Level.INFO, "Caps: " + caps); logger.log(Level.INFO, "Caps: " + caps);
} }
public void resetGLObjects(){ /**
* <code>resetGLObjects</code> should be called when die GLView gets recreated to reset all GPU objects
*/
public void resetGLObjects()
{
objManager.resetObjects(); objManager.resetObjects();
statistics.clearMemory(); statistics.clearMemory();
boundShader = null; boundShader = null;
@ -1853,16 +1861,27 @@ public class OGLESShaderRenderer implements Renderer {
img.clearUpdateNeeded(); img.clearUpdateNeeded();
} }
public void setTexture(int unit, Texture tex){ public void setTexture(int unit, Texture tex)
{
Image image = tex.getImage(); Image image = tex.getImage();
if (image.isUpdateNeeded()){ if (image.isUpdateNeeded())
{
Bitmap bmp = (Bitmap)image.getEfficentData();
// Check if the bitmap got recycled, can happen after wakeup/restart
if ( bmp.isRecycled() )
{
// We need to reload the bitmap
Texture textureReloaded = JmeSystem.newAssetManager().loadTexture((TextureKey)tex.getKey());
image.setEfficentData( textureReloaded.getImage().getEfficentData());
}
updateTexImageData(image, tex.getType(), tex.getMinFilter().usesMipMapLevels()); updateTexImageData(image, tex.getType(), tex.getMinFilter().usesMipMapLevels());
} }
int texId = image.getId(); int texId = image.getId();
assert texId != -1; assert texId != -1;
if (texId == -1) { if (texId == -1)
{
logger.warning("error: texture image has -1 id"); logger.warning("error: texture image has -1 id");
} }
@ -1877,8 +1896,10 @@ public class OGLESShaderRenderer implements Renderer {
// glEnable(type); // glEnable(type);
} }
if (textures[unit] != image){ if (textures[unit] != image)
if (context.boundTextureUnit != unit){ {
if (context.boundTextureUnit != unit)
{
if (verboseLogging) if (verboseLogging)
logger.info("GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + " + unit + ")"); logger.info("GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + " + unit + ")");
GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + unit); GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + unit);
@ -1892,7 +1913,9 @@ public class OGLESShaderRenderer implements Renderer {
textures[unit] = image; textures[unit] = image;
statistics.onTextureUse(tex.getImage(), true); statistics.onTextureUse(tex.getImage(), true);
}else{ }
else
{
statistics.onTextureUse(tex.getImage(), false); statistics.onTextureUse(tex.getImage(), false);
} }

@ -90,13 +90,32 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer
return Type.Display; return Type.Display;
} }
/**
* <code>createView</code>
* @param activity The Android activity which is parent for the GLSurfaceView
* @return GLSurfaceView The newly created view
*/
public GLSurfaceView createView(Activity activity) public GLSurfaceView createView(Activity activity)
{ {
return createView(new AndroidInput(activity)); return createView(new AndroidInput(activity));
} }
/**
* <code>createView</code>
* @param AndroidInput The Android input which must be bound to an activity
* @return GLSurfaceView The newly created view
*/
public GLSurfaceView createView(AndroidInput view) public GLSurfaceView createView(AndroidInput view)
{
return createView(view, 0);
}
/**
* <code>createView</code>
* @param AndroidInput The Android input which must be bound to an activity
* @param debugflags 0, GLSurfaceView.DEBUG_CHECK_GL_ERROR | GLSurfaceView.DEBUG_LOG_GL_CALLS
* @return GLSurfaceView The newly created view
*/
public GLSurfaceView createView(AndroidInput view, int debugflags)
{ {
this.view = view; this.view = view;
@ -112,11 +131,9 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer
view.setFocusableInTouchMode(true); view.setFocusableInTouchMode(true);
view.setFocusable(true); view.setFocusable(true);
view.getHolder().setType(SurfaceHolder.SURFACE_TYPE_GPU); view.getHolder().setType(SurfaceHolder.SURFACE_TYPE_GPU);
// view.setDebugFlags(GLSurfaceView.DEBUG_CHECK_GL_ERROR); view.setDebugFlags(debugflags);
// | GLSurfaceView.DEBUG_LOG_GL_CALLS);
view.setRenderer(this); view.setRenderer(this);
return view; return view;
} }
@ -252,11 +269,18 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer
// renderer:initialize // renderer:initialize
@Override @Override
public void onSurfaceCreated(GL10 gl, EGLConfig cfg) public void onSurfaceCreated(GL10 gl, EGLConfig cfg)
{
if (created.get() && renderer != null)
{
renderer.resetGLObjects();
}
else
{ {
logger.info("GL Surface created"); logger.info("GL Surface created");
initInThread(); initInThread();
renderable.set(true); renderable.set(true);
} }
}
// SystemListener:reshape // SystemListener:reshape
@Override @Override

Loading…
Cancel
Save