2012-05-15 48 views
4

當我在AsyncTask#doInBackground中使用Android上下文時,線程安全嗎?上下文是通過構造函數或通過周圍Activity的getApplicationContext()提供的。這個簡單的問題在stackoverflow被問及很多,但是我發現沒有一個明確的答案?Android上下文線程安全嗎?

E.g.在doInBackground()中,我使用上下文來實例化一個DAO類。

@Override 
protected Void doInBackground(Void... params) { 

    ExampleDao dao = new ExampleDao(context); 
    ... 

} 

我看見幾個例子做,在這種方式,但我不能想象這是線程安全的,因爲上下文現在由主胎面(UI線程)和工作者線程訪問。

+0

你能否請你多認真一點,你在做什麼? –

+0

爲什麼不應該是線程安全的?工作者線程使用上下文訪問文件系統,UI線程使用上下文處理所有與UI相關的內容。對於訪問相同資源的混合調用應該不會有問題等。 – Janusz

回答

5

只要不改變某些內容,並且只通過上下文檢索資源,您就可以始終訪問不同線程中的上下文。我沒有看到線程安全問題。

問題是,只要線程運行,上下文將保留在內存中並處於活動狀態。這對你來說是件好事,因爲你可以始終依賴有效的上下文。 糟糕的是,如果您將Activity作爲上下文傳遞,則此活動的所有視圖和成員變量也將保留在內存中,這可能會導致很長時間的垃圾回收,如Waqas所建議的。

在我不會從不同的線程做的事情是從上下文子類訪問方法,如setTheme(),這將影響當前顯示的視圖。

+0

聽起來不錯,因此您會優先使用getApplicationContext()而不是將整個活動傳遞給AsyncTask? – dan

+0

是的,傳遞應用程序上下文永遠不會對你造成任何傷害,並且保護你免受java中難以發現的奇怪內存問題的困擾。 – Janusz

2

如果你不需要用意見做任何事情然後總是嘗試使用getApplicationContext()是指應用程序的情況下(不活動的情況下),並可以幫助你避免內存泄漏,而線程或取向的變化。所以,我想它也適合您在AsyncTask中的需求。

+0

這意味着我可以從工作線程中的UI線程訪問上下文。 – dan

+0

是的......你可以。 – waqaslam

1

上下文實際上並不是線程安全的。但是可以傳遞一個應用程序上下文的實例來寫入數據庫。

+1

只是爲了我自己的知識,你能解釋一下「上下文不是線程安全」嗎?我的意思是,爲什麼不是? – waqaslam

+0

我的意思是從兩個不同的線程訪問上下文,在我的例子中是從UI線程和工作線程。 – dan

+1

這不是線程安全的,因爲沒有任何操作可以使寫讀操作同步。但由於你不寫任何東西,它可以從不同的線程使用。 –