diff options
| -rw-r--r-- | core/java/android/app/ActivityThread.java | 17 | ||||
| -rw-r--r-- | core/java/android/view/WindowManagerGlobal.java | 27 |
2 files changed, 33 insertions, 11 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 43238eceaffe..cfffe34486e3 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -4183,12 +4183,10 @@ public final class ActivityThread { // window is being added. r.mPendingRemoveWindow = r.window; r.mPendingRemoveWindowManager = wm; - if (r.mPreserveWindow) { - // We can only keep the part of the view hierarchy that we control, - // everything else must be removed, because it might not be able to - // behave properly when activity is relaunching. - r.window.clearContentView(); - } + // We can only keep the part of the view hierarchy that we control, + // everything else must be removed, because it might not be able to + // behave properly when activity is relaunching. + r.window.clearContentView(); } else { wm.removeViewImmediate(v); } @@ -4196,6 +4194,13 @@ public final class ActivityThread { if (wtoken != null && r.mPendingRemoveWindow == null) { WindowManagerGlobal.getInstance().closeAll(wtoken, r.activity.getClass().getName(), "Activity"); + } else if (r.mPendingRemoveWindow != null) { + // We're preserving only one window, others should be closed so app views + // will be detached before the final tear down. It should be done now because + // some components (e.g. WebView) rely on detach callbacks to perform receiver + // unregister and other cleanup. + WindowManagerGlobal.getInstance().closeAllExceptView(token, v, + r.activity.getClass().getName(), "Activity"); } r.activity.mDecor = null; } diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java index 887cc3acb64a..11734d31388e 100644 --- a/core/java/android/view/WindowManagerGlobal.java +++ b/core/java/android/view/WindowManagerGlobal.java @@ -391,17 +391,34 @@ public final class WindowManagerGlobal { } } + /** + * Remove all roots with specified token. + * + * @param token app or window token. + * @param who name of caller, used in logs. + * @param what type of caller, used in logs. + */ public void closeAll(IBinder token, String who, String what) { + closeAllExceptView(token, null /* view */, who, what); + } + + /** + * Remove all roots with specified token, except maybe one view. + * + * @param token app or window token. + * @param view view that should be should be preserved along with it's root. + * Pass null if everything should be removed. + * @param who name of caller, used in logs. + * @param what type of caller, used in logs. + */ + public void closeAllExceptView(IBinder token, View view, String who, String what) { synchronized (mLock) { int count = mViews.size(); - //Log.i("foo", "Closing all windows of " + token); for (int i = 0; i < count; i++) { - //Log.i("foo", "@ " + i + " token " + mParams[i].token - // + " view " + mRoots[i].getView()); - if (token == null || mParams.get(i).token == token) { + if ((view == null || mViews.get(i) != view) + && (token == null || mParams.get(i).token == token)) { ViewRootImpl root = mRoots.get(i); - //Log.i("foo", "Force closing " + root); if (who != null) { WindowLeaked leak = new WindowLeaked( what + " " + who + " has leaked window " |