I been playing around with a test app and must say I am very impressed so far. While playing around trying to learn the engine, I noticed some issues with handling the life cycle events.
When I hit the home button and then resume the app, the game would resume correctly. However, when I added a picture to the guiNode, when I resumed the game I recevied the following:
09-13 20:46:35.124: ERROR/AndroidHarness(12672): java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@4065af78
09-13 20:46:35.140: ERROR/AndroidHarness(12672): SEVERE AndroidHarness 8:46:35 PM Exception thrown in Thread[GLThread 9,5,main]: at android.graphics.Canvas.throwIfRecycled(955)
09-13 20:46:35.140: ERROR/AndroidHarness(12672): at android.graphics.Canvas.drawBitmap(1012)
09-13 20:46:35.140: ERROR/AndroidHarness(12672): at android.graphics.Bitmap.createBitmap(492)
09-13 20:46:35.140: ERROR/AndroidHarness(12672): at android.graphics.Bitmap.createScaledBitmap(379)
09-13 20:46:35.140: ERROR/AndroidHarness(12672): at com.jme3.renderer.android.TextureUtil.uploadTextureBitmap(95)
09-13 20:46:35.140: ERROR/AndroidHarness(12672): at com.jme3.renderer.android.TextureUtil.uploadTexture(123)
09-13 20:46:35.140: ERROR/AndroidHarness(12672): at com.jme3.renderer.android.OGLESShaderRenderer.updateTexImageData(1946)
09-13 20:46:35.140: ERROR/AndroidHarness(12672): at com.jme3.renderer.android.OGLESShaderRenderer.setTexture(1981)
09-13 20:46:35.140: ERROR/AndroidHarness(12672): at com.jme3.material.MatParamTexture.apply(46)
09-13 20:46:35.140: ERROR/AndroidHarness(12672): at com.jme3.material.Material.render(997)
09-13 20:46:35.140: ERROR/AndroidHarness(12672): at com.jme3.renderer.RenderManager.renderGeometry(656)
09-13 20:46:35.140: ERROR/AndroidHarness(12672): at com.jme3.renderer.queue.RenderQueue.renderGeometryList(301)
09-13 20:46:35.140: ERROR/AndroidHarness(12672): at com.jme3.renderer.queue.RenderQueue.renderQueue(354)
09-13 20:46:35.140: ERROR/AndroidHarness(12672): at com.jme3.renderer.RenderManager.renderViewPortQueues(918)
09-13 20:46:35.140: ERROR/AndroidHarness(12672): at com.jme3.renderer.RenderManager.flushQueue(849)
09-13 20:46:35.140: ERROR/AndroidHarness(12672): at com.jme3.renderer.RenderManager.renderViewPort(1125)
09-13 20:46:35.140: ERROR/AndroidHarness(12672): at com.jme3.renderer.RenderManager.render(1173)
09-13 20:46:35.140: ERROR/AndroidHarness(12672): at com.jme3.app.SimpleApplication.update(263)
09-13 20:46:35.140: ERROR/AndroidHarness(12672): at com.jme3.system.android.OGLESContext.onDrawFrame(418)
09-13 20:46:35.140: ERROR/AndroidHarness(12672): at android.opengl.GLSurfaceView$GLThread.guardedRun(1363)
09-13 20:46:35.140: ERROR/AndroidHarness(12672): at android.opengl.GLSurfaceView$GLThread.run(1118)
While searching through the jme3 source code for android, I found that OGLESShaderRenderer.setTexture had some commented-out code to handle recycled images. When I uncommented the code, the error went away and the games would resume correctly.
Is there a reason why this code was commented-out?
When the orientation mode in main game class (the class I have that extends AndroidHarness) is set to SCREEN_ORIENTATION_SENSOR, the game restarts when the phone is rotated and the orientation changes. I tried to figure out if there was a way to make the game pause and resume when the orientation changes, but I’m afraid that might be beyond what I understand about jme.
Is there a way to make the game pause/resume when the orientation changes instead of restarting the game?
While creating the test case for you, I found out that using an image from the test-data jar file (Interfaces/icons/SmartMonkey128.png) does not have the issue while using my own picture from the assets directory does have the problem. I left both in for you below. When the app first displays, both pictures show correctly. After I hit the home key and then go back, I get the issue, but only if the second picture (the only from the assets directory) is used.
Hope this helps.
[java]
package com.interstatewebgroup.jmonkeytutorials;
import android.util.Log;
import com.jme3.app.SimpleApplication;
import com.jme3.ui.Picture;
public class RecycleTestGame extends SimpleApplication {
Forget to add that even when I use pictures from the assests directory, when I add back in the code from OGLESShaderRenderer.setTexture both pictures display fine on the resume.
I am seeing the same issue using Nifty GUI on Android. I am testing on a Motorola Xoom.
I see this crash when I resume the app:
E/AndroidHarness( 1879): java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@408d7908
E/AndroidHarness( 1879): SEVERE AndroidHarness 10:19:35 PM Exception thrown in Thread[GLThread 15,5,main]: at android.graphics.Canvas.throwIfRecycled(1012)
E/AndroidHarness( 1879): at android.graphics.Canvas.drawBitmap(1084)
E/AndroidHarness( 1879): at android.graphics.Bitmap.createBitmap(569)
E/AndroidHarness( 1879): at android.graphics.Bitmap.createScaledBitmap(437)
E/AndroidHarness( 1879): at com.jme3.renderer.android.TextureUtil.uploadTextureBitmap(95)
E/AndroidHarness( 1879): at com.jme3.renderer.android.TextureUtil.uploadTexture(123)
E/AndroidHarness( 1879): at com.jme3.renderer.android.OGLESShaderRenderer.updateTexImageData(1954)
E/AndroidHarness( 1879): at com.jme3.renderer.android.OGLESShaderRenderer.setTexture(1989)
E/AndroidHarness( 1879): at com.jme3.material.MatParamTexture.apply(46)
E/AndroidHarness( 1879): at com.jme3.material.Material.render(1002)
E/AndroidHarness( 1879): at com.jme3.font.BitmapText.render(360)
E/AndroidHarness( 1879): at com.jme3.niftygui.RenderDeviceJme.renderFont(225)
E/AndroidHarness( 1879): at de.lessvoid.nifty.render.NiftyRenderEngineImpl.renderText(258)
E/AndroidHarness( 1879): at de.lessvoid.nifty.elements.render.TextRenderer.renderLine(291)
E/AndroidHarness( 1879): at de.lessvoid.nifty.elements.render.TextRenderer.renderLines(192)
E/AndroidHarness( 1879): at de.lessvoid.nifty.elements.render.TextRenderer.render(173)
E/AndroidHarness( 1879): at de.lessvoid.nifty.elements.Element.renderElement(599)
E/AndroidHarness( 1879): at de.lessvoid.nifty.elements.Element.render(584)
E/AndroidHarness( 1879): at de.lessvoid.nifty.elements.Element.renderInternalChildElements(616)
E/AndroidHarness( 1879): at de.lessvoid.nifty.elements.Element.renderChildren(609)
E/AndroidHarness( 1879): at de.lessvoid.nifty.elements.Element.render(578)
E/AndroidHarness( 1879): at de.lessvoid.nifty.elements.Element.renderInternalChildElements(616)
E/AndroidHarness( 1879): at de.lessvoid.nifty.elements.Element.renderChildren(609)
E/AndroidHarness( 1879): at de.lessvoid.nifty.elements.Element.render(578)
E/AndroidHarness( 1879): at de.lessvoid.nifty.screen.Screen.renderLayers(313)
E/AndroidHarness( 1879): at de.lessvoid.nifty.Nifty.render(276)
E/AndroidHarness( 1879): at com.jme3.niftygui.NiftyJmeDisplay.postQueue(170)
E/AndroidHarness( 1879): at com.jme3.renderer.RenderManager.renderViewPort(1121)
E/AndroidHarness( 1879): at com.jme3.renderer.RenderManager.render(1167)
E/AndroidHarness( 1879): at com.jme3.app.SimpleApplication.update(266)
E/AndroidHarness( 1879): at com.jme3.system.android.OGLESContext.onDrawFrame(418)
E/AndroidHarness( 1879): at android.opengl.GLSurfaceView$GLThread.guardedRun(1425)
E/AndroidHarness( 1879): at android.opengl.GLSurfaceView$GLThread.run(1180)
I tried the above fix, but my jmonkey built from source had other issues so I went back to the Beta (nightly) release.
I finally got this resolved. The problem seems to be that my images were not sized with a power of 2. The original pictures were 48x48 pixels. When I resized the images to 64x64 pixels, the issues with trying to display recycled images on the GUI node when the game resumes went away. Does that make sense?