- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
WindowManager.removeViewImmediate()
的文档包含警告(强调我的):
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.
我很好奇这里的“精心呵护”到底是什么意思。大概这表明我不应该调用此方法,除非我知道如何处理使用它的所有副作用......但我什至不知道这些副作用可能是什么。
考虑以下 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);
}
}
当我运行我的应用程序并将我的设备从纵向旋转到横向(或任何其他导致它被破坏和重新创建的东西)时,这会出现在 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)
但是,如果我将 onDestroy()
方法更改为使用 removeViewImmedate()
,则此错误永远不会出现在我的日志中。不过,我对此犹豫不决,因为我不知道切换这些电话还会影响什么。仅仅说“它有效”并不足以让我放心。
最佳答案
WinowManager 由 WindowManagerImpl 实现。
WindowManagerImpl#removeViewImmediate(View)
和 WindowManagerImpl#removeView(View)
都调用WindowManagerGlobal#removeView(View, boolean)
.
区别在于removeViewImmediate()
通过 true
到那个 bool 参数,它告诉 WindowManagerGlobal 应该立即删除该 View 而不是等待。
虽然这可能是不言自明的。
我能想到的唯一可能导致立即删除的问题是奇怪的绘图错误。虽然对源方法的评论如下:
/** * @param immediate True, do now if not in traversal. False, put on queue and do later. * @return True, request has been queued. False, request has been completed. */
没有多大意义。
老实说,如果它不会导致崩溃,而是会删除泄漏警告,那么您不妨使用它。
关于android - 正确使用 WindowManager.removeViewImmediate(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52726870/
WindowManager.removeViewImmediate() 的文档包含警告(强调我的): Special variation of ViewManager.removeView(View)
我是一名优秀的程序员,十分优秀!