3737import android .view .ViewGroup ;
3838import android .view .Window ;
3939import android .view .WindowManager ;
40+ import android .view .WindowManagerGlobal ;
4041import android .view .WindowManager .LayoutParams ;
4142import android .view .accessibility .AccessibilityEvent ;
4243
@@ -510,8 +511,12 @@ public final void finish() {
510511 @ Override
511512 public void onDestroy () {
512513 if (mDebug ) Slog .v (TAG , "onDestroy()" );
513- super .onDestroy ();
514514 // hook for subclasses
515+
516+ // Just in case destroy came in before detach, let's take care of that now
517+ detach ();
518+
519+ super .onDestroy ();
515520 }
516521
517522 // end public api
@@ -521,13 +526,13 @@ private void loadSandman() {
521526 }
522527
523528 /**
524- * Called when the Dream is about to be unbound and destroyed.
529+ * Called by DreamController.stopDream() when the Dream is about to be unbound and destroyed.
525530 *
526531 * Must run on mHandler.
527532 */
528533 private final void detach () {
529534 if (mWindow == null ) {
530- Slog . e ( TAG , "detach() called when not attached" );
535+ // already detached!
531536 return ;
532537 }
533538
@@ -540,7 +545,11 @@ private final void detach() {
540545
541546 if (mDebug ) Slog .v (TAG , "detach(): Removing window from window manager" );
542547 try {
543- mWindowManager .removeView (mWindow .getDecorView ());
548+ // force our window to be removed synchronously
549+ mWindowManager .removeViewImmediate (mWindow .getDecorView ());
550+ // the following will print a log message if it finds any other leaked windows
551+ WindowManagerGlobal .getInstance ().closeAll (mWindowToken ,
552+ this .getClass ().getName (), "Dream" );
544553 } catch (Throwable t ) {
545554 Slog .w (TAG , "Crashed removing window view" , t );
546555 }
0 commit comments