WindowManager.removeViewImmediate()
的文档包含警告(强调我的意思):
ViewManager.removeView(View)
的特殊变体,在返回之前立即调用给定视图层次结构的View.onDetachedFromWindow()
方法。 这不适用于普通应用;正确使用它需要格外小心。
我很好奇“精心护理”在这里的含义。大概这表明除非我知道如何处理使用它的所有副作用,否则我不应该调用此方法……但是我什至不知道这些副作用可能是什么。
请考虑以下活动,我已尽可能将其制成。没有遗漏的代码(除了导入),并且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);
}
}
当我运行我的应用程序并将设备从纵向旋转到横向(或导致其被破坏并重新创建的任何其他方式)时,这将出现在日志栏中:
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)
但是,如果我将onDestroy()
方法更改为使用removeViewImmedate()
,则此错误将永远不会出现在日志中。不过,我很犹豫,因为我不知道切换这些呼叫还会影响什么。仅仅说“有效”不足以让我放心。
答案 0 :(得分:0)
WinowManager由WindowManagerImpl实现。
WindowManagerImpl#removeViewImmediate(View)
和WindowManagerImpl#removeView(View)
都呼叫WindowManagerGlobal#removeView(View, boolean)
。
区别在于removeViewImmediate()
将true
传递给该布尔参数,该变量告诉WindowManagerGlobal该View应该立即删除而不是等待。
虽然这可能很不言自明。
我唯一想到的可能是立即删除一个问题是奇怪的绘图错误。在对源方法的评论中说:
/ ** * @param Instant True,请立即进行遍历。错误,请排队,然后再做。 * @return True,请求已排队。错误,请求已完成。 * /
这没有多大意义。
老实说,如果它不会导致崩溃,而是删除该泄漏警告,则最好使用它。