Closed ravenfeld closed 10 years ago
I found a solution, but I do not know if it's very safe Thread:
Modified the method onDestroy in Wallpaper.java
@Override
public void onDestroy() {
setTouchEventsEnabled(false);
mRenderer.onSurfaceDestroyed();
mRenderer = null;
mSurfaceView.onDestroy();
super.onDestroy();
}
and the method onSurfaceChanged in RajawaliRenderer.java
mViewportWidth = width;
mViewportHeight = height;
mTextureManager = TextureManager.getInstance();
mTextureManager.setContext(this.getContext());
mTextureManager.registerRenderer(this);
mMaterialManager = MaterialManager.getInstance();
mMaterialManager.setContext(this.getContext());
mMaterialManager.registerRenderer(this);
if (!mSceneInitialized) {
getCurrentScene().resetGLState();
initScene();
}
....
Now you must destroy in onSurfaceDestroyed your items in your Renderer
mMaterial.removeTexture(mTexture);
mTexture.reset();
mTextureManager.taskRemove(mTexture);
mMaterialManager.taskRemove(mMaterial);
Hi RavenFeld !
I have this issue and wasn't able to correct it since i'm new in programming. I'm really pleased to see that someone found a solution AND explain how to put it in place ! thank you very much !
BUT ! still had issue for the last step !
So i added in my renderer right after the InitScene{.......}
public void onSurfaceDestroyed() { mMaterial.removeTexture(mTexture); mTexture.reset(); mTextureManager.taskRemove(mTexture); mMaterialManager.taskRemove(mMaterial); } but looks like Eclipse can't find my mMaterial and mTexture... ??? Thank you in Advance
it's your Texture and your Material
Show me initScene and I'll tell you how you have called ?
public void initScene() {
ALight frontlight = new SpotLight();
frontlight.setPosition(0, -1.3f, 4);
frontlight.setPower(1.2f);
frontlight.setLookAt(0,0,0);
getCurrentScene().addLight(frontlight);
OrthographicCamera camera = new OrthographicCamera();
camera.setPosition(0, 0, 5);
camera.setLookAt(0, 0, 0);
camera.setRotation(0,0,0);
replaceAndSwitchCamera(camera, 0);
try {
Plane background = new Plane(4,2.3f,2,2);
background.setBlendingEnabled(true);
background.setBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
background.setDoubleSided(true);
Material mbackground = new Material();
mbackground.setDiffuseMethod(new DiffuseMethod.Lambert());
Texture t = new Texture("mbackground", R.drawable.background);
t.setRepeat(2, 1); // Tile Texture
mbackground.addTexture(mTextureManager.addTexture(t));
mbackground.setColorInfluence(0);
background.setMaterial(mbackground);
background.setPosition(0, 0, -10);
background.setRotation(0, 0, 0);
addChild(background);
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
super.onSurfaceCreated(gl, config);
}
public void onDrawFrame(GL10 glUnused) {
super.onDrawFrame(glUnused);
}
public void onSurfaceDestroyed() {
mMaterial.removeTexture(background);
mTexture.reset();
mTextureManager.taskRemove();
mMaterialManager.taskRemove(mMaterial);
}
}
i believe i have to change mMaterial by mbackground and mTexture by t ? .... thank you for the fast reply :)
Yes but they must be in class variable
any precision ? i cant figure out... sorry for being annoying ....
private Material mBackgroundTexture;
private Texture mBackgroundTexture;
public void initScene() {
ALight frontlight = new SpotLight();
frontlight.setPosition(0, -1.3f, 4);
frontlight.setPower(1.2f);
frontlight.setLookAt(0,0,0);
getCurrentScene().addLight(frontlight);
OrthographicCamera camera = new OrthographicCamera();
camera.setPosition(0, 0, 5);
camera.setLookAt(0, 0, 0);
camera.setRotation(0,0,0);
replaceAndSwitchCamera(camera, 0);
try {
Plane background = new Plane(4,2.3f,2,2);
background.setBlendingEnabled(true);
background.setBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
background.setDoubleSided(true);
mBackgroundMaterial = new Material();
mBackgroundMaterial.setDiffuseMethod(new DiffuseMethod.Lambert());
mBackgroundTexture = new Texture("mBackgroundMaterial", R.drawable.background);
mBackgroundTexture.setRepeat(2, 1); // Tile Texture
//don't use mTextureManager.addTexture
mBackgroundMaterial.addTexture(mBackgroundTexture);
mBackgroundMaterial.setColorInfluence(0);
background.setMaterial(mBackgroundMaterial);
background.setPosition(0, 0, -10);
background.setRotation(0, 0, 0);
addChild(background);
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
super.onSurfaceCreated(gl, config);
}
public void onDrawFrame(GL10 glUnused) {
super.onDrawFrame(glUnused);
}
public void onSurfaceDestroyed() {
mBackgroundMaterial.removeTexture(mBackgroundTexture);
mBackgroundTexture.reset();
mTextureManager.taskRemove(mBackgroundTexture);
mMaterialManager.taskRemove(mBackgroundMaterial);
}
}
Test this code
Oh well i understand a little bit more how it works now thank you !
but the livewallpaper crashes lol ....
10-25 18:19:55.864: E/AndroidRuntime(4370): FATAL EXCEPTION: main 10-25 18:19:55.864: E/AndroidRuntime(4370): java.lang.NullPointerException 10-25 18:19:55.864: E/AndroidRuntime(4370): at livewallpaper.doodah.Renderer.onSurfaceDestroyed(Renderer.java:566) 10-25 18:19:55.864: E/AndroidRuntime(4370): at rajawali.wallpaper.Wallpaper$WallpaperEngine.onDestroy(Wallpaper.java:370) 10-25 18:19:55.864: E/AndroidRuntime(4370): at android.service.wallpaper.WallpaperService$Engine.detach(WallpaperService.java:917) 10-25 18:19:55.864: E/AndroidRuntime(4370): at android.service.wallpaper.WallpaperService$IWallpaperEngineWrapper.executeMessage(WallpaperService.java:1036) 10-25 18:19:55.864: E/AndroidRuntime(4370): at com.android.internal.os.HandlerCaller$MyHandler.handleMessage(HandlerCaller.java:40) 10-25 18:19:55.864: E/AndroidRuntime(4370): at android.os.Handler.dispatchMessage(Handler.java:99) 10-25 18:19:55.864: E/AndroidRuntime(4370): at android.os.Looper.loop(Looper.java:137) 10-25 18:19:55.864: E/AndroidRuntime(4370): at android.app.ActivityThread.main(ActivityThread.java:5103) 10-25 18:19:55.864: E/AndroidRuntime(4370): at java.lang.reflect.Method.invokeNative(Native Method) 10-25 18:19:55.864: E/AndroidRuntime(4370): at java.lang.reflect.Method.invoke(Method.java:525) 10-25 18:19:55.864: E/AndroidRuntime(4370): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737) 10-25 18:19:55.864: E/AndroidRuntime(4370): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 10-25 18:19:55.864: E/AndroidRuntime(4370): at dalvik.system.NativeStart.main(Native Method)
Well, i'll look about it later !! thanks for your help !!
add super. onSurfaceDestroyed();
public void onSurfaceDestroyed() {
mBackgroundMaterial.removeTexture(mBackgroundTexture);
mBackgroundTexture.reset();
mTextureManager.taskRemove(mBackgroundTexture);
mMaterialManager.taskRemove(mBackgroundMaterial);
super. onSurfaceDestroyed();
}
i added super.onSurfaceDestroyed(); but the crash is still there ! i googled it and it seems to be a common bug with live wallpaper but i'm not able to find the right solution.
Could you put your project on your github or send it to me by email?
So i declared my var as you told me and it looks like it works fine now ! Thanks !!
Hi ravenfield! I think you might have answered my problem too. It's cost me about 60 potential buyers, I reckon, as sometimes it would happen straight away. My code is a bit more complex with multiple texture sheets for quality v performance reasons. I'm really hoping that you can help me too.
My wallpaper is based on the particle example, and as such it uses it's own material class which extends AParticleMaterial:
// textures/materials
private myParticleMaterial tex032sheet1Mat;
private myParticleMaterial tex064sheet1Mat;
private Texture tex032sheet1Tex;
private Texture tex064sheet1Tex;
Anyway... in InitScene:
tex032sheet1Mat = new myParticleMaterial();
tex064sheet1Mat = new myParticleMaterial();
tex032sheet1Tex = new Texture(R.drawable.tex032sheet1);
tex064sheet1Tex = new Texture(R.drawable.tex064sheet1);
tex032sheet1Mat.addTexture(tex032sheet1Tex);
tex064sheet1Mat.addTexture(tex064sheet1Tex);
Note that I can't do "tex032sheet1Tex = new Texture("tex032sheet1Mat", R.drawable.tex032sheet1);", as per your example.
My onSurfaceDestroyed is:
tex032sheet1Mat.removeTexture(tex032sheet1Tex);
tex064sheet1Mat.removeTexture(tex064sheet1Tex);
//tex032sheet1Tex.reset();
//tex064sheet1Tex.reset();
mTextureManager.taskRemove(tex032sheet1Tex);
mTextureManager.taskRemove(tex064sheet1Tex);
mMaterialManager.taskRemove(tex032sheet1Mat);
mMaterialManager.taskRemove(tex064sheet1Mat);
super. onSurfaceDestroyed();
Note that my resets are commented out - this is because there is no reset() method!!
I'm not using 0.9 Rajawali so maybe that's the issue, but particles seem to have been removed from the master, so I can't point you in the direction of the version of Rajawali that I'm using.
Can you help with the reset?? Is the two parameter texture declaration required, or will my single parameter do?
Thanks for any help that you can provide.
PS - My onSurfaceChanged in RajawaliRenderer is this, as it wasn't clear whether to leave the old lines there or not...
public void onSurfaceChanged(GL10 gl, int width, int height) {
mViewportWidth = width;
mViewportHeight = height;
//https://github.com/MasDennis/Rajawali/issues/1103
mTextureManager = TextureManager.getInstance();
mTextureManager.setContext(this.getContext());
mTextureManager.registerRenderer(this);
mMaterialManager = MaterialManager.getInstance();
mMaterialManager.setContext(this.getContext());
mMaterialManager.registerRenderer(this);
if (!mSceneInitialized) {
getCurrentScene().resetGLState();
initScene();
}
mCurrentScene.updateProjectionMatrix(width, height);
GLES20.glViewport(0, 0, width, height);
}
Do I just use you lines and remove the other stuff?
Can you retrieve your project somewhere? Did you try to put android: largeHeap = "true" in your manifest ?
largeHeap="true" is a great help!
Closing this as a duplicate to #1138
When set their livewallpaper then returns to the preview. Rajawali will not go in to taskReset TextureManager because there are two instances of Renderer. How to release the textures used in the instance of the preview? Currently if you go much on the preview, the application crash with OutOfMemory.
I do not know if it's related but if you look with DDMS threads you will see that whenever we create a preview there is a new GLThread.
thank you