跟踪添加到 WindowManager 的视图(没有 findViewById() 函数?)

发布于 2024-11-17 12:49:57 字数 601 浏览 2 评论 0原文

在我的服务中,我使用 addView() 将视图添加到 WindowManager 中。当我准备好隐藏视图时,我使用 View 引用调用 removeView()。这在大多数情况下都非常有效。

我偶尔会收到强制关闭报告,指出视图未附加到 WindowManager。这是有道理的。问题是我认为该服务被 Android 杀死了,当需要隐藏视图时,它会尝试在错误的 View 上删除 View。

我已尝试检查视图是否为空,但显然此时它不是空的,它根本不是附加到 WindowManager 的视图。看来,如果视图引用丢失,就无法再次访问它。

如何在 WindowManager 本身上获得与 findViewById() 等效的内容?如果我的服务停止(终止),View 是否会自动从 WindowManager 中删除?有没有办法可以存储对 View 的引用,以便在服务停止时我仍然可以稍后删除 View (我也试图避免泄漏查看)?

In my service I add a view to WindowManager with addView(). When I'm ready to hide the view, I call removeView() using the View reference. This works great -- most of the time.

I have occasional Force Close reports that say that the View is not attached to the WindowManager. This makes sense. The problem is that I think the service is getting killed by Android, and when it is time to hide the view, it attempts to removeView on the wrong View.

I have tried checking for the View to be null, but apparently it isn't at this point, it simply isn't the one attached to the WindowManager. It seems that if the View reference is lost, there is no way to gain access to it again.

How can I get the equivalent of findViewById() on the WindowManager itself? Is the View automatically removed from WindowManager if my service is stopped (killed)? Is there a way I can store the reference to the View so that if the service is stopped I can still remove the View later (I'm also trying to avoid leaking the View)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

淡看悲欢离合 2024-11-24 12:49:57

在我的服务中,我使用 addView() 将视图添加到 WindowManager。当我准备好隐藏视图时,我使用 View 引用调用removeView()。这在大多数情况下都非常有效。我偶尔会收到强制关闭报告,指出视图未附加到 WindowManager。

我遇到了完全相同的问题。希望有专家指点一下。

如何在 WindowManager 本身上获得相当于 findViewById() 的功能?

保留对添加的视图的引用,只需使用removeView(mView)即可。

目前在我的服务中,要添加视图:

WindowManager.LayoutParams params = ...
mView = new View(this);
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
wm.addView(mView, params);

然后要删除视图,我通过捕获异常来避免偶尔发生 FC:

WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
try {
    wm.removeView(mView);
} catch (Exception e) {}

如果我的服务停止(终止),视图是否会自动从 WindowManager 中删除?

根据我的经验,当服务被终止时它们会被删除。您可以通过停止服务而不删除视图来测试这一点。不知道为什么会这样。

我担心的是,当我去删除视图时,我对 WM 的第二次引用是不同的。如果是这样的话,当我捕获异常时,mView是否仍然显示?当我添加视图时,我会尝试保留对 WM 的引用,但我遇到了一些问题,即对系统服务的引用似乎随着时间的推移而变坏。

如果您解决了这个问题,请告诉我。

In my service I add a view to WindowManager with addView(). When I'm ready to hide the view, I call removeView() using the View reference. This works great--most of the time. I have occasional Force Close reports that say that the View is not attached to the WindowManager.

I am having the exact same problem. Hopefully an expert will chime in.

How can I get the equivalent of findViewById() on the WindowManager itself?

Keep a reference to the View that was added and simply use removeView(mView).

Currently in my Service, to add the view:

WindowManager.LayoutParams params = ...
mView = new View(this);
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
wm.addView(mView, params);

Then to remove the view, I avoid occasional FC by catching the exception:

WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
try {
    wm.removeView(mView);
} catch (Exception e) {}

Is the View automatically removed from WindowManager if my service is stopped (killed)?

In my experience, they are removed when the service is killed. You can test this by stopping your service without removing the views. No idea why that works though.

My concern is that my second reference to the WM is different when I go to remove the view. If that is the case, is mView still being displayed when I catch the exception? I would try keeping a reference to the WM when I add the view, but I've had issues where references to System Services seem to go bad over time.

Let me know if you ever solved this problem.

橘和柠 2024-11-24 12:49:57

要检查视图是否已成功附加到 Windows Manager,或者仍然附加,您可以使用 view.isShown();。

To check if view has been succesfully attached to Windows Manager, or is still attached, you can use view.isShown();.

烟沫凡尘 2024-11-24 12:49:57

在尝试删除视图之前,请检查其父视图是否为 != null。

if(mView.getParent() != null){
   wm.removeView(mView);
}

Check that the views parent != null before trying to remove it.

if(mView.getParent() != null){
   wm.removeView(mView);
}
忆伤 2024-11-24 12:49:57

您还可以使用:

ViewCompat.isAttachedToWindow(mView);

根据文档:

如果提供的视图当前附加到窗口,则返回 true。

You can also use:

ViewCompat.isAttachedToWindow(mView);

According the docs:

Returns true if the provided view is currently attached to a window.

缺⑴份安定 2024-11-24 12:49:57

我通过在 imageView 上添加此代码来删除布局

layoutView.findViewById(R.id.close).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

              windowManager.removeView(layoutView);
            }
        });

i have remove the layout by adding this code on an imageView

layoutView.findViewById(R.id.close).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

              windowManager.removeView(layoutView);
            }
        });
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文