2011-06-29 56 views
14

在我的服務中,我使用addView()添加了一個視圖到WindowManager。當我準備隱藏視圖時,我使用View參考號碼撥打removeView()。這很有用 - 大部分時間。跟蹤添加到WindowManager的視圖(無findViewById()函數?)

我有偶爾的強制關閉報告,表示該視圖未附加到WindowManager。這是有道理的。問題是我認爲該服務正在被Android殺死,當它是隱藏視圖的時候,它會嘗試刪除錯誤的View

我已經嘗試檢查視圖爲空,但顯然它不是在這一點上,它只是不是附加到WindowManager。看起來,如果查看引用丟失,則無法再次訪問它。

我怎樣才能在WindowManager本身上得到相當於findViewById()?如果我的服務停止(殺死),View是否自動從WindowManager中刪除?有沒有一種方法可以存儲對View的引用,以便如果服務停止,我仍然可以在以後刪除View(我也試圖避免泄漏View)?

+0

我知道這是舊的,但你爲什麼要從服務中與UI進行交互?!? – Dori

+0

@Dori我想覆蓋來電屏幕,但在Android中沒有這樣做的機制(到目前爲止)。最好的解決方案是在來電屏幕上顯示一個視圖,並且一個活動對此不可靠。服務讓我可以跟蹤視圖並在不再需要時隱藏視圖。 – Jesta

回答

10

在我的服務中,我使用addView()向WindowManager添加了一個視圖。當我準備隱藏視圖時,我使用視圖引用調用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的引用,但是我遇到了隨着時間的推移系統服務的引用似乎變差的問題。

讓我知道你是否曾經解決過這個問題。

+1

這是一個非常好的問題:對WindowManager的新引用是否仍然允許訪問已添加到其中的原始「mView」?除此之外,你的代碼看起來與我使用的基本相同。最初,我並沒有捕捉到關於.removeView()的(看似隨機的)異常,但現在我認爲該應用程序運行得更好。我仍然想知道是否讓視圖自動刪除是可以接受的練習,或者如果每次我的服務被殺時視圖實際上都在泄漏!謝謝@kevin! – Jesta

+0

我面臨着與wm.removeView(mView)相同的問題; –

+1

視圖不會在錯誤日誌中泄漏,我也使用catch語句來防止此錯誤。現在我試圖跟蹤顯示的視圖數量,就像谷歌跟蹤位圖並在舊平臺上回收它們一樣。查看Google deverloper文檔,瞭解如何有效使用位圖以查看一些有趣的跟蹤想法(請參閱舊API部分)。 – AutoM8R

5

要檢查視圖是否已成功連接到Windows管理器,或仍然連接,可以使用view.isShown();

+0

view.isShown如果視圖連接到窗口但不可見(它是不可見或不存在),則返回false也是如此 http://developer.android.com/reference/android/view/View.html#isShown() – Massimo

2

在嘗試刪除視圖之前,請檢查視圖parent!= null。

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

您還可以使用:

ViewCompat.isAttachedToWindow(mView); 

根據文檔:

返回true如果提供了查看當前連接到一個窗口。