2

我正在寫這個問題的基礎上的一些事實。 如我們無法明確控制垃圾收集器(GC)。因此也無法檢查GC何時會從暫停的活動中獲取內存。簡歷時間內存優化

我在說的測試案例: 我已經在我的onCreate方法中分配了許多對象,包括HashMaps和ArrayLists。 其中一些用於存儲位圖的引用。 現在用戶正在按主頁按鈕暫停活動。 比我忘記在長時間執行其他任務後恢復同一個人。 現在,當我回到我暫停的活動。

問題是:1)在這種情況下,是否有機會假裝或假設memeory GC將首先獲取?

2)gc是否僅獲取整個活動或幾個空閒和空對象?

3)假設經過長時間約5至6小時用戶正在恢復活動,我怎麼知道一些對象是垃圾收集。

4)如果某些對象是垃圾收集而不是在onResume中檢查它們是否爲null,則可以進一步訪問它們。

5)如何在這種情況下處理空指針訪問。

我很想聽聽每一個建議。 謝謝你的期待。 快樂編碼。

回答

1

據我所知GC運行,而忽視了在VM的所有對象,如果有對象沒有引用,它被刪除。它有自己的lifecycle有關Android活動有點不同。
當Android需要更多RAM用於其他應用(活動)時,則在您的活動onSaveInstanceState (Bundle outState)中被調用。在這個地方,你應該保存你需要的一切Bundle當用戶回到你的Activity時,你可以在onRestoreInstanceState(Bundle savedInstanceState)中恢復這些對象。

編輯:我的應用程序的片爲例:

public class Window { 
    public Window(Bundle bundle) { 
     maximized = bundle.getBoolean("maximized", maximized); 
     displayed = bundle.getBoolean("displayed", displayed); 
     minimized = bundle.getBoolean("minimized", minimized); 
     resizable = bundle.getBoolean("resizable", resizable); 
     orientation = bundle.getInt("orientation"); 
    } 
    public Bundle bundle() { 
     Bundle bundle = new Bundle(); 
     bundle.putBoolean("maximized", maximized); 
     bundle.putBoolean("displayed", displayed); 
     bundle.putBoolean("minimized", minimized); 
     bundle.putBoolean("resizable", resizable); 
     bundle.putInt("orientation", orientation); 
     return bundle; 
    } 
} 

而且MainActivity:

public class MainActivity extends Activity { 
    ArrayList<Window> windows; 
    [...] 

    @Override 
    public void onSaveInstanceState(Bundle savedInstanceState) { 
     super.onSaveInstanceState(savedInstanceState); 
     Bundle[] windowsBundle = new Bundle[windows.size()]; 
     for(int i=0; i<windowsBundle.length; i++){ 
      windowsBundle[i] = windows.get(i).bundle(); 
     } 
     savedInstanceState.putParcelableArray("windows", windowsBundle); 
    } 
    @Override 
    public void onRestoreInstanceState(Bundle savedInstanceState){ 
     super.onRestoreInstanceState(savedInstanceState); 
     Parcelable[] windowsParcels = savedInstanceState.getParcelableArray("windows"); 
     Bundle[] windowsBundle = (Bundle[]) Arrays.copyOf(windowsParcels, windowsParcels.length, Bundle[].class); 
     windowsParcels = null; 
     for(int i=0; i<windowsBundle.length; i++){ 
      windows.add(new Window(windowsBundle[i])); 
     } 
    } 
} 
+0

你的意思是我應該對每個活動都做,即使我在我的應用程序內導航。 –

+0

是的。保存每個對象以捆綁可能看起來很累人,但人們一直認爲這是保存活動數據的最佳方式。 – RedScorpio

1

如果你的活動已在後臺5或6小時,這幾乎保證Android已經殺死了主機進程。當用戶返回到您的應用程序時,Android將爲應用程序創建一個新的進程,然後重新實例化一個活動。一般來說,5或6個小時後,Android會放棄任何保存的狀態,並從一開始就重新啓動您的應用程序(除非您已針對您的根活動(開始活動)特別指定android:alwaysRetainTaskState="true"

如果您返回您的'暫停'活動5或6小時後,應用程序的進程已被殺死並重新創建,onCreate()將再次在您的活動之前被調用onResume()

GC與此無關如果您的活動實例處於活動狀態,GC不會回收它引用的任何對象。如果您看到變量設置爲null,這是因爲Android已經殺死了您的進程,然後又創建了一個新進程。

+1

那麼AFAIK的android只會殺死你的活動或(應用程序)在內存不足的情況下,並基於頻繁的使用情況,我真的懷疑它是否殺死任何暫停的活動只是基於time.I真的對你的答案感興趣,因爲如果它殺死處理它的必要,以釋放它分配的所有內存引用。這裏來自GC的照片。 –

+1

實際上,Android可以隨時殺死你的進程(如果它在後臺)。在較新的設備上(Android 4.0及更高版本),特別是在HTC設備上,「進程查殺」更具侵略性。在大多數情況下,如果您的應用程序在後臺超過幾分鐘,可能會被殺死。請查看[here](http://developer.android.com/guide/topics/manifest/activity-element.html#always),瞭解Android在清除任務30分鐘後清除任務的說明。 –

+0

關於你對GC和進程查殺的評論,你有這個錯誤:當Android殺死你的進程時,它只會殺死OS進程。繁榮。不見了。它不會在任何組件上調用onDestroy(),它根本不會調用GC,因爲當它終止進程時,VM(虛擬機)也會被終止,所以它不需要清理任何資源。 Android做了很多,你需要確保你的代碼可以處理它。 –