Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Keeping track of View added to WindowManager (no findViewById() function?)

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)?

like image 417
Jesta Avatar asked Jun 29 '11 01:06

Jesta


4 Answers

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.

like image 124
kevin Avatar answered Nov 14 '22 09:11

kevin


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

like image 41
Szymon Mazurczak Avatar answered Nov 14 '22 09:11

Szymon Mazurczak


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

if(mView.getParent() != null){
   wm.removeView(mView);
}
like image 34
Tyler Pfaff Avatar answered Nov 14 '22 07:11

Tyler Pfaff


You can also use:

ViewCompat.isAttachedToWindow(mView);

According the docs:

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

like image 38
yshahak Avatar answered Nov 14 '22 07:11

yshahak