5

I am currently working on a live wallpaper that is very intensive and does not handle screen rotation very well.

In fact the wallpaper is destroyed and displays a blank screen without calling onSurfaceChanged!

Here is what I have within the onSurfaceChanged method:

@Override
    public void onSurfaceChanged(SurfaceHolder holder, int format,
            int width, int height) {
        // TODO Auto-generated method stub
        super.onSurfaceChanged(holder, format, width, height);

        mRatio = (float) width / height;
        if (mRatio > 1) {
            orientation = 0;
        }
        if (mRatio < 1) {
            orientation = 1;
        }
        setRunning(true);
        Log.i(TAG, "Screen Rotation...");
        mHandle.post(r);
    }

I am positive this method does not get called because there is no log message.

Why is this happening and what are some techniques for handling screen rotation? Could it be that my live wallpaper is so intensive the void cannot be called?

Also, onVisibilityChanged is not called as well and when I open apps on the emulator, there is no log message:

@Override
    public void onVisibilityChanged(boolean visible) {
        // TODO Auto-generated method stub
        super.onVisibilityChanged(visible);
        if (visible) {
            setRunning(true);
            Log.i(TAG, "Visible...");
            mHandle.postDelayed(r, 2000);
        } else {
            setRunning(false);
            Log.i(TAG, "Invisible...");
            mHandle.removeCallbacks(r);
        }
    }
Denizen
  • 335
  • 5
  • 17
  • Could you post more code? Need to know where all the heavy work is done. In my Live Wallpaper, both onSurfaceChanged and onVisibilityChanged gets called during screen rotations. Also, check you LogCat for something like "Timeout waiting for wallpaper to offset" during orientation changing. – Ole Jun 17 '12 at 13:49

1 Answers1

1

In your manifest, declare:

    <activity android:name=".YourActivityName"
              android:configChanges="keyboardHidden|orientation"
    </activity>

Your onSurfaceChanged-method be only be called if declare theconfigChanges-attribute in the manifest!

Regarding your second issue: onVisibilityChanged is not what you would expect from the name:

Called when the window containing has change its visibility (between GONE, INVISIBLE, and VISIBLE). Note that this tells you whether or not your window is being made visible to the window manager; this does not tell you whether or not your window is obscured by other windows on the screen, even if it is itself visible.

You need to check whether your app is "visible" to the user via onPause() and onResume()

Nick
  • 3,504
  • 2
  • 39
  • 78
  • Thanks for the response, I changed my live wallpaper service to this: - and it doesn't work :( – Denizen Jun 17 '12 at 14:20
  • My problem is that im constantly initializing 20 rectangles and have 40 or so if statements for animating them. The if statements are constantly being checked even when im done animating slowing down performance – Denizen Jun 17 '12 at 14:26
  • 1
    The above answer does not apply to live wallpapers, but for applications using SurfaceView. So setting the configChanges-attribute will do nothing. Please post more code.. – Ole Jun 17 '12 at 14:39
  • public void drawSurface() { mRectArray = new Rect[] { initialize 20 rectgles };, if(statement){ if(statement) {animate rectangles}}.. repeat if statements 40 times, c.drawRect(mRectArray[x])... draw 40 rectangles } - void is being looped – Denizen Jun 17 '12 at 14:52
  • Why do you initialize new Rects in your drawing method? Initializing 20 new rectangles every loop will drastically decrease performance. Resource initialization should be done in Engine or WallpaperService onCreate() method. And you probably do not need 40 if statements, remember that you got for, while and switch loops in your arsenal too.. – Ole Jun 17 '12 at 15:02
  • mRectArray = new Rect[] { new Rect(0, 0, right1, (c.getHeight() + statusBarHeight) / 20), new Rect(0, (c.getHeight() + statusBarHeight) / 20, right2, (c.getHeight() + statusBarHeight) / 20 * 2),... }; - do you see how I have a variable for the right side of each rectangle? The if statements merely increase or decrease the sides of each rectangle. Now, in order to animate the rectangles, they have to be reinitialized or the right side of each rectangle won't get updated. – Denizen Jun 17 '12 at 15:17
  • Hmm..., should I use more if statements to only initialize the rectangles when they are being animated? – Denizen Jun 17 '12 at 15:25
  • You don't have to initialize new Rects to be able to animate them. The dimensions can be changed using Rect.left, Rect.right etc.. If you have 20 rectangles, and every time you want to animate them you init new ones, you are going to get really bad performance. You have posted your onSurfaceChanged and onVisibilityChanged methods, but I think the problems you face stems from your main drawing method. A complete source would be helpful, or at least the part of your code that does the drawing... – Ole Jun 17 '12 at 18:35