2016-09-29 71 views
0

當一個類包含靜態的Context對象時,Android Studio現在會顯示警告。它說這會導致內存泄漏。不過,我注意到這也是在android庫中完成的。例如,LocalBroacastManager類有一個靜態實例,它包含一個context對象。靜態上下文警告

那麼作爲內存泄漏有多糟?

我有一個singleton geofencing類,它在後臺運行,並將boolean保存到sharedPreferences,指示用戶是否在geofence中。爲了保存首選項,我需要一個context對象,但由於該方法是重寫的方法,因此我無法傳遞上下文對象。

如何在不使用context實例變量的情況下完成此任務?

回答

2

它關於你可以有最糟糕的。讓我們說你有一個Activity,並把它作爲一個靜態的Context來存儲。除非您在活動結束時將其清空,否則您現在已經泄露了整個活動。這意味着活動所持有的每個變量都會泄露,包括整個視圖層次結構。它基本上阻止了這種情況下的任何事情的解放。

要做的最好的事情不是存儲上下文,而是將其作爲參數傳遞給需要它的函數。如果您必須存儲上下文,請勿將其設爲靜態。只要框架中的任何內容在活動完成後繼續保持對對象的引用,非靜態變量就不會泄漏它。

如果您絕對必須使用靜態上下文,請將其設置爲應用程序上下文。這是一個在你的應用程序的長度有效,所以它不能真正泄漏。

1

靜態應該很少使用,特別是在Android。有使用靜力學的方法和原因,但在90%的情況下,這只是對它們的濫用。

保持上下文爲靜態變量是一個很大的禁忌。想象一下以下情形:

  1. 您從一個活動到活動B.
  2. 而在b活動你保持活性B參考靜態語境地方。
  3. 你回到活動A.活動B應該被銷燬,但是它被保留下來,因爲你保留了對它的靜態引用。
  4. 現在你再次從A等到B,你有兩個B實例:一個是你看到的,另一個是靜態上下文。

您可能永遠不會有兩個相同活動的實例。這可能會導致很多問題。

現在,我意識到許多開發人員(甚至是製作庫的人)偶爾會犯錯並使用反模式,所以您不應該盲目地依賴別人代碼中看到的練習/模式。地獄,我甚至在谷歌開發者寫的東西中看到了很多垃圾代碼。如果你真的需要一個單例(不是單例模式(大寫S)),而是某個類的單個實例,如果你不想使用像Dagger這樣的庫,那麼你可以在你的Application類中實例化這個類,然後從任何你想要的地方引用它。

+0

實際上,大多數人發現應用程序對象作爲單身持有者最近已經是一個時代錯誤。它不會優於使用靜態。使用靜態來創建單例沒有問題,但不應該用來保存上下文。 –

+0

將objets保存爲靜態並以這種方式訪問​​它們意味着共享狀態,這是避免的。另外,單身模式製作的舊單身不能被繼承和擴展。如果只需要一個類的實例 - 只需創建一個實例並使用IoC,就可以在需要的地方使用該實例。我不確定爲什麼它是不合時宜的,Application類是單類和幾乎在類/依賴關係樹中的頂級類,就像在普通Java應用程序中持有main()方法的類一樣,可以成爲實例化ssingleton的根位。 – SadClown