2011-09-15 35 views
2

我正在使用SMACK編寫XMPP客戶端。Android runOnUiThread - 如何通過活動

所以,當我想更新我的contactList - ListAdapter.notifyDataSetChanged需要在UI線程中運行,但顯然SMACK庫在RosterListener上使用多線程(實際上是一件好事)。但問題在於:運行s.th.在UI線程中,我需要一個有效的上下文。

但我該如何得到它?將活動的上下文傳遞給RosterListener的註冊函數是我想到的第一個 - 但是在我到達註冊函數之前,我在不同的類中有一些函數,而且我不太喜歡它通過上下文一遍又一遍,直到它最終到達目的地,它將被使用。

我想,我不是唯一一個遇到過這個問題的人,那麼你會如何解決它?也許是一個單身人士,只是爲了挽救這一個背景(在我看來,這是一個更不利的想法......) 或者也許是我的整個設計有缺陷? 是否有可能從任何地方獲得UI線程?

底線:我沒有真正的線索如何處理它,此刻我通過多個函數傳遞上下文作爲參數,但有沒有更好的方法來做到這一點。

感謝您的任何幫助。

回答

1

將XMPP代碼放入服務中,然後發送廣播。感興趣的活動可以簡單地註冊這些廣播。這樣你永遠不會再擔心UI線程和Activity上下文的可用性。

+0

這是一個絕妙的主意,特別是對於聊天客戶端來說,後臺服務非常有用 - 它也解決了我的問題。謝謝;-) –

+0

那麼你可能想接受這個答案,對吧? –

0

讀你,我得到一個感覺就像你在使用回調工作。 Smack或其他任何從工作者線程調回給您的內容,並且您希望在發生這種情況時發佈到主UI線程。

根據我的經驗,回調函數總是可以與註冊回調時通過的自定義數據相關聯,並在實際回調時接收回調。

在你的背景有哪些,我認爲是設計較差兩種方法:

  • 使用任何一種全球性的啄的,把它如果你喜歡
  • 一個單讓你的模型期待並返回( Android和UI特定)上下文

相反,我會創建一個由Activity實現的小接口,讓Model接受此接口的一個實例,並且將它傳遞到不同的層直到註冊。

該接口公開的方法將被異步調用,您可以正確編制文檔,以指示必須使用runOnUiThread()或類似方法。

這樣,您並不是完全將Context(這是一個平臺和UI細節)遍佈整個地方並傳入Model中。另外,您避免了全局/靜態數據,這會導致各種問題,衝突和其他內存泄漏。

1

我發現了一個更整潔,更模塊化的方式。爲此,您需要定義一個Application Context。一旦你有了這個,你可以從任何一個類庫中調用RunOnUIThread,而不會引用Activity

從您的類庫調用內的任何地方:

Handler handler = new Handler(Application.Context.MainLooper); 
handler.Post(() => doStuff()); 

請記住,這是用C#編寫,因爲我用MonoDroid的,但我認爲這是非常類似於Java。 如何創建一個ApplicationContext看看這個thread