I'm developing a Live Wallpaper for Honeycomb 3.0, but I get a random error.
When I'm in wallpaper picker (the window with "Set Wallpaper" and "Settings..." buttons, to understand) and Live Wallpaper is displayed, if I rotate the device, the wallpaper should reload with the configuration adapted for new orientation. Sometimes it does, sometimes it crashes.
The error is in some way related to BaseSurfaceHolder.unlockCanvasAndPost method, but I really don't know were is the issue. I think it cannot load correctly some resources..
Here's error log:
07-21 16:07:38.490: WARN/WindowManager(292): java.lang.IllegalArgumentException: Requested window android.os.BinderProxy@40d19f28 does not exist
07-21 16:07:38.490: WARN/WindowManager(292): at com.android.server.wm.WindowManagerService.windowForClientLocked(WindowManagerService.java:6731)
07-21 16:07:38.490: WARN/WindowManager(292): at com.android.server.wm.WindowManagerService.windowForClientLocked(WindowManagerService.java:6722)
07-21 16:07:38.490: WARN/WindowManager(292): at com.android.server.wm.WindowManagerService.removeWindow(WindowManagerService.java:2414)
07-21 16:07:38.490: WARN/WindowManager(292): at com.android.server.wm.Session.remove(Session.java:149)
07-21 16:07:38.490: WARN/WindowManager(292): at android.view.IWindowSession$Stub.onTransact(IWindowSession.java:120)
07-21 16:07:38.490: WARN/WindowManager(292): at com.android.server.wm.Session.onTransact(Session.java:111)
07-21 16:07:38.490: WARN/WindowManager(292): at android.os.Binder.execTransact(Binder.java:320)
07-21 16:07:38.490: WARN/WindowManager(292): at dalvik.system.NativeStart.run(Native Method)
07-21 16:07:38.490: ERROR/AndroidRuntime(20768): FATAL EXCEPTION: main
07-21 16:07:38.490: ERROR/AndroidRuntime(20768): java.lang.IllegalArgumentException
07-21 16:07:38.490: ERROR/AndroidRuntime(20768): at android.view.Surface.unlockCanvasAndPost(Native Method)
07-21 16:07:38.490: ERROR/AndroidRuntime(20768): at com.android.internal.view.BaseSurfaceHolder.unlockCanvasAndPost(BaseSurfaceHolder.java:215)
07-21 16:07:38.490: ERROR/AndroidRuntime(20768): at mx.livewallpaper.clock.CubeWallpaper1$CubeEngine.drawFrame(CubeWallpaper1.java:686)
07-21 16:07:38.490: ERROR/AndroidRuntime(20768): at mx.livewallpaper.clock.CubeWallpaper1$CubeEngine$1.run(CubeWallpaper1.java:292)
07-21 16:07:38.490: ERROR/AndroidRuntime(20768): at android.os.Handler.handleCallback(Handler.java:587)
07-21 16:07:38.490: ERROR/AndroidRuntime(20768): at android.os.Handler.dispatchMessage(Handler.java:92)
07-21 16:07:38.490: ERROR/AndroidRuntime(20768): at android.os.Looper.loop(Looper.java:132)
07-21 16:07:38.490: ERROR/AndroidRuntime(20768): at android.app.ActivityThread.main(ActivityThread.java:4028)
07-21 16:07:38.490: ERROR/AndroidRuntime(20768): at java.lang.reflect.Method.invokeNative(Native Method)
07-21 16:07:38.490: ERROR/AndroidRuntime(20768): at java.lang.reflect.Method.invoke(Method.java:491)
07-21 16:07:38.490: ERROR/AndroidRuntime(20768): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:844)
07-21 16:07:38.490: ERROR/AndroidRuntime(20768): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
07-21 16:07:38.490: ERROR/AndroidRuntime(20768): at dalvik.system.NativeStart.main(Native Method)
07-21 16:07:38.500: ERROR/android.os.Debug(292): Dumpstate > /data/log/dumpstate_app_error
EDIT: code below is the drawFrame() method at line 686:
void drawFrame() {
final SurfaceHolder holder = getSurfaceHolder();
Canvas c = null;
try {
c = holder.lockCanvas();
if (c != null) {
drawLogo3(c);
}
} finally {
if (c != null) holder.unlockCanvasAndPost(c);
}
It's a default method ppresent in all live wallpapers, I took it from CubeWallpaper Live Wallpaper Sample from Android SDK.
EDIT 2:
It sounds like a buffer error. If I set the framerate to 10fps instead of 40fps, the Live Wallpaper Picker doesn't crash at all. Is it possible to edit Live Wallpaper behaviour only for the Activity "Live Wallpaper Picker"?
have the thread join before you destroy the surface
@Override
public void onSurfaceDestroyed(SurfaceHolder holder)
{
try
{
updater.join();
}
catch (InterruptedException e)
{
}
super.onSurfaceDestroyed(holder);
}
when you change the orientation of device,the function "onsurfacechange()" called.you must do somthing there.I guess the when you change the orientant the "surfaceholder"also changed.I do it like :
@Override
public void onSurfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
int lockwidth = 0;
int lockheight = 0;
mholder = holder;
try {
canvas = mholder.lockCanvas();
lockwidth = canvas.getWidth();
lockheight = canvas.getHeight();
if (width > height) {
Utils.Width = lockheight;
Utils.screenWidth = lockheight;
Utils.screenHeight = lockwidth;
Utils.isWidth = true;
if (width == 1280 && height == 720 && lockwidth == 800
&& lockheight == 480) {
Utils.screenWidth = 480;
Utils.screenHeight = 854;
}
} else {
Utils.Width = lockwidth;
Utils.screenWidth = lockwidth;
Utils.screenHeight = lockheight;
Utils.isWidth = false;
if (width == 720 && height == 1280 && lockwidth == 480
&& lockheight == 800) {
Utils.screenWidth = 480;
Utils.screenHeight = 854;
}
}
mholder.unlockCanvasAndPost(canvas);
} catch (Exception e) {
}
Utils.rateX = (float) Utils.Width / (float) Utils.FLA_Width;
Utils.ratio = Utils.screenWidth / Utils.FLA_Width;
Utils.Width = lockwidth;
Utils.Height = lockheight;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With