The documentation for WindowManager.removeViewImmediate()
contains a warning (emphasis mine):
Special variation of
ViewManager.removeView(View)
that immediately invokes the given view hierarchy'sView.onDetachedFromWindow()
methods before returning. This is not for normal applications; using it correctly requires great care.
I'm curious what exactly "great care" means here. Presumably this is an indication that I shouldn't be calling this method unless I know how to handle all of the side-effects of using it... but I don't even know what those side-effects might be.
Consider the following Activity, which I've made as vanilla as possible. There's no omitted code (other than imports), and the Activity's theme is just a vanilla AppCompat theme:
public class MainActivity extends AppCompatActivity {
private View overlay;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().getDecorView().post(() -> {
overlay = new View(this);
overlay.setBackgroundColor(Color.RED);
WindowManager.LayoutParams params =
new WindowManager.LayoutParams(WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindowManager().addView(overlay, params);
});
}
@Override
protected void onDestroy() {
super.onDestroy();
getWindowManager().removeView(overlay);
}
}
When I run my app, and rotate my device from portrait to landscape (or anything else that causes it to be destroyed and recreated), this appears in the logcat:
2018-10-09 13:58:02.162 11270-11270/com.example.stackoverflow E/WindowManager: android.view.WindowLeaked: Activity com.example.stackoverflow.MainActivity has leaked window android.view.View{e99861 V.ED..... ........ 0,0-1080,1920} that was originally added here at android.view.ViewRootImpl.<init>(ViewRootImpl.java:511) at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:346) at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:93) at com.example.stackoverflow.MainActivity.lambda$onCreate$0(MainActivity.java:25)
However, if I change my onDestroy()
method to use removeViewImmedate()
instead, then this error never appears in my logs. I'm hesitant to do this, though, because I don't know what else could be affected by switching these calls. Just saying "it works" isn't enough to put my mind at ease.