服務來來去去 - 作爲OSGi開發人員的職責是隻有在服務已經發布時才使用服務,更重要的是在未發佈服務時發佈服務。如果您在未發佈服務後繼續使用服務,則可能會發生不可預知的錯誤。至少你會導致與該服務實例關聯的堆空間被固定在內存中,這會破壞OSGi動態安裝和卸載軟件包的能力。
所以,你問你是否應該在使用該服務之前關閉ServiceTracker:我的回答是否。 ServiceTracker作爲當前服務的「智能指針」,它管理所有監聽器等,以便在服務消失時得到通知。如果關閉跟蹤器,則不再保持服務狀態的最新狀態,那麼如何知道它是否仍然有效?
了使用ServiceTracker的理想模式 - 假設跟蹤保持整個開放 - 如下:
{
Service svc = tracker.getService();
svc.doSomething();
}
// 'svc' is now forgotten, and may be garbage collected
也就是說,當你在跟蹤調用getService()
您獲得實際的實例服務,但您應該儘快使用它,然後儘快將其忘記。您絕對不能將getService()
的結果存儲在一個字段中,並堅持很長時間。
至於是否應打開,並立即關閉跟蹤器僅在需要時 - 不,這完全沒有必要這麼做。開放的追蹤器不消耗任何重要的資源,它僅僅意味着它被註冊爲一個監聽器,以便它知道服務何時來去。事實上,重複打開和關閉跟蹤器是無效的,因爲每次打開跟蹤器時,都必須與服務註冊表的當前狀態進行同步。這就是爲什麼您在示例中看到的模式通常是在激活束期間打開跟蹤器並將其保持打開狀態......這是最好的模式。
順便也沒有必要在你的BundleActivator.stop
方法明確地關閉跟蹤。與您的跟蹤器相關的所有資源將在捆綁停止時自動清除。明確關閉的唯一原因是如果您有多個跟蹤器和/或服務註冊,並且您想控制清理的順序。
現在說了以上全部內容,我要去查一個手榴彈:請停止使用ServiceTracker
!這是一個非常低級的實用程序,只是很少需要,然後只在「管道」或基礎結構代碼中。大多數應用程序應該建立在更高級別的抽象層次上。我強烈建議使用聲明式服務,這比纏繞ServiceTracker更容易。
不錯的方式把它。 「如果你不得不問如何使用它,你就不應該使用它。」 :-) –