WindowManager.removeViewImmediate() 的文档包含一个警告(强调我的意思):



我很好奇“精心护理”在这里意味着什么。大概这表明我不应该调用此方法,除非我知道如何处理使用它的所有副作用...但是我什至不知道这些副作用可能是什么。

考虑以下 Activity ,我尽可能将其制成。没有遗漏的代码(除了导入),并且Activity的主题只是一个普通的AppCompat主题:

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);
    }
}

当我运行我的应用程序,并将设备从纵向旋转到横向(或导致其被破坏和重新创建的其他任何方式)时,这将显示在日志中:



但是,如果我将onDestroy()方法更改为改为使用removeViewImmedate(),则此错误永远不会出现在我的日志中。不过,我很犹豫,因为我不知道切换这些调用还会影响什么。仅仅说“有效”不足以让我放心。

最佳答案

WinowManager由WindowManagerImpl实现。
WindowManagerImpl#removeViewImmediate(View)WindowManagerImpl#removeView(View)都称为WindowManagerGlobal#removeView(View, boolean)

区别在于removeViewImmediate()true传递给该 bool 参数,该参数告诉WindowManagerGlobal该View应该立即删除而不是等待。

不过,这可能很不言自明。

我唯一想到的可能是立即清除问题,那就是奇怪的绘图错误。尽管对源方法的评论如下:



这没有多大意义。

老实说,如果它不会导致崩溃,而是删除该泄漏警告,则最好使用它。

WindowManagerGlobal#removeViewLocked(View, boolean)

ViewRootImpl#die(boolean)

10-07 23:21