2011-06-29 10 views
14

W mojej usłudze dodam widok do WindowManager z addView(). Kiedy jestem gotowy, aby ukryć widok, zadzwonię pod numer removeView(), używając odnośnika View. Działa to świetnie - przez większość czasu.Śledzenie widoku dodanego do WindowManagera (brak funkcji findViewById()?)

Mam sporadyczne raporty dotyczące zamknięcia siły, które mówią, że widok nie jest dołączony do WindowManager. To ma sens. Problem polega na tym, że usługa jest zabijana przez Androida, a kiedy nadszedł czas, aby ukryć widok, próbuje usunąć ViewView na niewłaściwym View.

Próbowałem sprawdzić, czy widok ma wartość zerową, ale najwyraźniej nie ma go w tym momencie, to po prostu nie jest dołączony do WindowManager. Wygląda na to, że jeśli odniesienie do Widoku zostanie utracone, nie ma możliwości ponownego dostępu do niego.

Jak uzyskać odpowiednik findViewById() na samym WindowManager? Czy usługa View zostanie automatycznie usunięta z WindowManager, jeśli moja usługa zostanie zatrzymana (zabita)? Czy istnieje sposób, w jaki mogę zapisać odniesienie do View, więc jeśli usługa zostanie zatrzymana, nadal mogę usunąć później View (staram się również unikać przeciekania View)?

+0

Wiem, że to stary, ale dlaczego interakcji z interfejsem użytkownika z usługi?!? – Dori

+0

@Dori Chciałem przesłonić ekran połączenia przychodzącego, ale nie ma na to żadnego mechanizmu w Androidzie (do tej pory). Najlepszym rozwiązaniem jest pokazanie widoku ekranu połączenia przychodzącego, a działanie jest niewiarygodne. Usługa pozwala mi śledzić widok i ukrywać go, gdy nie jest już potrzebny. – Jesta

Odpowiedz

10

W mojej usłudze dodam widok do programu WindowManager za pomocą metody addView(). Kiedy jestem gotowy, aby ukryć widok, wywołuję removeView() używając odwołania do widoku. Działa to świetnie - przez większość czasu. Mam sporadyczne raporty Force Close, które mówią, że widok nie jest dołączony do WindowManager.

Mam dokładnie ten sam problem. Mam nadzieję, że ekspert zadzwoni.

Jak mogę uzyskać ekwiwalent findViewById() w samym WindowManagerze?

Zachowaj odwołanie do widoku, który został dodany i po prostu użyj removeView (mView).

Obecnie w mojej służbie, aby dodać widok:

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

Następnie do usuwania pogląd, unikam sporadyczne FC łapiąc wyjątek:

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

jest widok automatycznie usuwane z WindowManager, jeśli moja usługa zostanie zatrzymana (zabita)?

Z mojego doświadczenia wynika, że ​​są one usuwane po zabiciu usługi. Możesz to sprawdzić, zatrzymując usługę bez usuwania widoków. Nie mam pojęcia, dlaczego to działa.

Moim zmartwieniem jest to, że moje drugie odniesienie do WM jest inne, gdy idę, aby usunąć widok. Jeśli tak, to czy mView jest nadal wyświetlany, gdy przechwycę wyjątek? Próbowałbym zachować odniesienie do WM po dodaniu widoku, ale miałem problemy, w których odniesienia do usług systemowych wydają się z czasem zepsuć.

Daj mi znać, jeśli kiedykolwiek rozwiązałeś ten problem.

+1

To bardzo dobre pytanie: czy nowe odniesienie do WindowManagera nadal daje dostęp do oryginalnego "mView", który został do niego dodany? Poza tym twój kod wygląda na identyczny z tym, którego używam. Oryginalnie nie łapałem (pozornie przypadkowych) wyjątków związanych z .removeView(), ale teraz, gdy jestem, myślę, że aplikacja działa znacznie lepiej. Nadal chcę wiedzieć, czy zezwolenie na automatyczne usunięcie Widoku to akceptowalna praktyka, czy też Widok faktycznie przecieka za każdym razem, gdy moja usługa zostanie zabita! Dzięki @kevin! – Jesta

+0

Mam do czynienia z tym samym problemem dotyczącym wm.removeView (mView); –

+1

Widok nie wycieka w dziennikach błędów, używam również instrukcji catch, aby zapobiec temu błędowi. Obecnie próbuję śledzić liczbę wyświetlanych wyświetleń, podobnie jak Google, do śledzenia bitmap i ich recyklingu na starszych platformach. Zapoznaj się z dokumentami od Rozgrywek Google dotyczącymi efektywnego korzystania z bitmap, aby zobaczyć ciekawe pomysły na śledzenie (patrz starsza sekcja API). – AutoM8R

5

Aby sprawdzić, czy widok został pomyślnie przyłączony do Menedżera systemu Windows, lub nadal jest podłączony, można użyć view.isShown();.

+0

view.isShown zwraca również wartość false, jeśli widok jest dołączony do okna, ale nie jest widoczny (jest niewidoczny lub nie ma go) http://developer.android.com/reference/android/view/View.html#isShown() – Massimo

2

Sprawdź, czy widoki parent! = Null przed próbą usunięcia.

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

Można również użyć:

ViewCompat.isAttachedToWindow(mView); 

Według docs:

Zwraca true, jeśli warunkiem pogląd jest obecnie przypisane do okna.

Powiązane problemy