Skip to content

Fix crash when the view was not removed from the window manager in time.#24

Open
gw0 wants to merge 1 commit intopingpongboss:masterfrom
gw0:fix-prevent-adding-view-again
Open

Fix crash when the view was not removed from the window manager in time.#24
gw0 wants to merge 1 commit intopingpongboss:masterfrom
gw0:fix-prevent-adding-view-again

Conversation

@gw0
Copy link

@gw0 gw0 commented Oct 3, 2014

Running applications that use StandOutWindow again without closing them before results in a crash. For StandOut/example the window disappears and the Service prints out the following exception:

10-03 09:37:16.885  30030-30030/wei.mark.example W/System.err﹕ java.lang.IllegalStateException: View wei.mark.standout.ui.Window{421d2e98 V.E..... ......ID 0,0-250,300} has already been added to the window manager.
10-03 09:37:16.895  30030-30030/wei.mark.example W/System.err﹕ at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:230)
10-03 09:37:16.895  30030-30030/wei.mark.example W/System.err﹕ at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
10-03 09:37:16.895  30030-30030/wei.mark.example W/System.err﹕ at wei.mark.standout.StandOutWindow.show(StandOutWindow.java:1102)
10-03 09:37:16.895  30030-30030/wei.mark.example W/System.err﹕ at wei.mark.standout.StandOutWindow.onStartCommand(StandOutWindow.java:381)
10-03 09:37:16.895  30030-30030/wei.mark.example W/System.err﹕ at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2719)
10-03 09:37:16.895  30030-30030/wei.mark.example W/System.err﹕ at android.app.ActivityThread.access$2100(ActivityThread.java:144)
10-03 09:37:16.895  30030-30030/wei.mark.example W/System.err﹕ at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1302)
10-03 09:37:16.895  30030-30030/wei.mark.example W/System.err﹕ at android.os.Handler.dispatchMessage(Handler.java:102)
10-03 09:37:16.905  30030-30030/wei.mark.example W/System.err﹕ at android.os.Looper.loop(Looper.java:136)
10-03 09:37:16.905  30030-30030/wei.mark.example W/System.err﹕ at android.app.ActivityThread.main(ActivityThread.java:5139)
10-03 09:37:16.905  30030-30030/wei.mark.example W/System.err﹕ at java.lang.reflect.Method.invokeNative(Native Method)
10-03 09:37:16.905  30030-30030/wei.mark.example W/System.err﹕ at java.lang.reflect.Method.invoke(Method.java:515)
10-03 09:37:16.905  30030-30030/wei.mark.example W/System.err﹕ at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:796)
10-03 09:37:16.905  30030-30030/wei.mark.example W/System.err﹕ at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:612)
10-03 09:37:16.905  30030-30030/wei.mark.example W/System.err﹕ at dalvik.system.NativeStart.main(Native Method)

The problematic line in StandOutWindow.java is:

            // add the view to the window manager
            mWindowManager.addView(window, params);

Although the code in Activity looks like:

        StandOutWindow.closeAll(this, WidgetsWindow.class);
        StandOutWindow.show(this, SimpleWindow.class, StandOutWindow.DEFAULT_ID);

The problem originates in the fact that the close/hide animation take some time to finish and it doesn't remove the window from the window manager immediately.

The included patch resolves this by forceful removing of the view from the window manager before adding it again.

@gw0
Copy link
Author

gw0 commented Oct 3, 2014

You are right. Modifying it to the following does not result in window disappearing if a start animation is specified. But the documentation for getShowAnimation() states that you may return null to disable the animation and in this case it doesn't work.

        try {
            // add the view to the window manager
            mWindowManager.addView(window, params);
        } catch (IllegalStateException ex) {
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        // animate
        if (animation != null) {
            window.getChildAt(0).startAnimation(animation);
        }

@pingpongboss
Copy link
Owner

Can you clarify what you mean by "in this case it doesn't work"? What happens, and what do you expect to happen?

If it's about clearing the previous animation, there is View#clearAnimation

@gw0
Copy link
Author

gw0 commented Oct 3, 2014

Starting the application in the usual way two times (without closing the window between) one would expect the window to remain visible without any exception. But what happens:

  • in original code: window disappears and exception gets printed out (PROBLEM)
  • with code from the previous comment and getShowAnimation() returning an animation: window reappears with start animation and no exception (OK)
  • with code from the previous comment and getShowAnimation() returning null: window disappears and no exception (PROBLEM)

So the problem is that the window is not visible if addView(window, params) fails and window.getChildAt(0).startAnimation(animation) is not called. Is there any other way of making the window visible?

addView() fails because the hide/close animation from the StandOutWindow.closeAll(this, WidgetsWindow.class) intent still hasn't finished and consequently hasn't called removeView() at the time the StandOutWindow.show(this, SimpleWindow.class, StandOutWindow.DEFAULT_ID) gets called. And because startAnimation() is not called if start animation is disabled, the window is not shown.

@pingpongboss
Copy link
Owner

I see. For the 3rd case, when getShowAnimation() returns null, you can just directly set window.getChildAt(0).setAlpha(1f);

PS: did window.getChildAt(0).clearAnimation() not work?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants