gpt4 book ai didi

android - 正确使用 WindowManager.removeViewImmediate()

转载 作者:太空宇宙 更新时间:2023-11-03 10:58:03 24 4
gpt4 key购买 nike

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

Special variation of ViewManager.removeView(View) that immediately invokes the given view hierarchy's View.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. */

没有多大意义。

老实说,如果它不会导致崩溃,而是会删除泄漏警告,那么您不妨使用它。

WindowManagerGlobal#removeViewLocked(View, boolean)

ViewRootImpl#die(boolean)

关于android - 正确使用 WindowManager.removeViewImmediate(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52726870/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com