歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> 如何避免Android內存洩漏

如何避免Android內存洩漏

日期:2017/3/1 10:35:29   编辑:Linux編程

至少在T-Mobile G1上Android應用在堆上分配的內存大小被限制16MB以內。對於手機來說,這是個不小的內存,但是這仍然遠遠不能滿足一些開發者的需求。但是,即使你不打算使用所有的內存空間,你也應該盡可能地少用內存,從而使得其他應用能夠運行而不是被殺掉。因為Android能夠在內存中保持的應用越多,那麼用戶切換應用的速度就會越快。作為我工作的一部分,我在做android應用開發的時候也會陷入內存洩漏的問題中,大多數時候內存的洩漏都是由於犯了相同的錯誤:長期持有了一個Context的引用。

Android上 ,Context可以用於很多操作,但是大部分時候是用來加載以及使用資源。這就是為什麼所有的widgets在他們的構造函數中接受一個Context參數。在一般的android應用中,你通常有兩種Context:分別是Activity和Application。通常的,當我們的類和方法需要使用到context時,我們傳遞的是Activity這個context:

[java]
  1. @Override
  2. protected void onCreate(Bundle state) {
  3. super.onCreate(state);
  4. TextView label = new TextView(this);
  5. label.setText("Leaks are bad");
  6. setContentView(label);
  7. }

這意味著views擁有一個對整個activity的引用,也就是引用了你的activity所擁有的一切;通常的,這指的是完整的視圖層級結構以及所有它的資源。因此,如果你洩露了一個Context(“ 洩漏 ”意味著你保持著它的一個引用,從而使它不能被垃圾回收機制回收),就意味著你洩漏了很多的內存。如果你不小心, 洩漏一 個activity的所有資源真的非常容易。

當 屏幕的方向發生改變的時候,系統默認將會銷毀當前的activity並且創建一個新的activity同時保持著原有的狀態。在做這個的時候,Android會從資源重新加載應用的UI。現在,想象一下你寫了一個應用,這個應用有一張很大的bitmap。你不想再每一次旋轉的時候重新加載它。最簡單的方法讓bitmap持續作用而不隨每一個方向而重新加載 ,就是把它放進一個靜態域:

[java]
  1. private static Drawable sBackground;
  2. @Override
  3. protected void onCreate(Bundle state) {
  4. super.onCreate(state);
  5. TextView label = new TextView(this);
  6. label.setText("Leaks are bad");
  7. if (sBackground == null) {
  8. sBackground = getDrawable(R.drawable.large_bitmap);
  9. }
  10. label.setBackgroundDrawable(sBackground);
  11. setContentView(label);
  12. }
這段代碼很快,但是錯誤也很嚴重:它洩漏了第一個activity,這個在第一次屏幕改變時被創建的activity。當一個Drawable被關聯到一個view上,這個view就相當於在drawable上設置的一個回調。在上面的代碼片段中,這表示drawable有一個TextView的引用,而這個TextView又擁有一個activity的引用(Context),activity依次引用了幾乎所有的東西(取決於你的代碼)。
Copyright © Linux教程網 All Rights Reserved