Activity生命週期 之 停止和重啓Acitivty

恰當的停止和重新啓動你的activity,在activity的生命週期裏面這個是非常重要的,這種機制可以讓用戶的覺得你的APP一直是在運行的,即使他不在你的程序的activity界面,但是並不會丟失這個程序的運行進度.下面是幾個重要的使用場景:

  • 當用戶打開最近使用的APP程序列表(長按HOME按鍵),這個時候用戶選擇一個APP,那麼用戶就由你的APP轉移進入到另外一個APP裏面,你的APP將不再前臺運行,而當用戶再次打開最近使用的程序列表,選擇打開你的APP的時候,這個時候你的APP又重新啓動了。
  • 當用戶在你的應用上進行一個操作,啓動了另外一個新的Activity(一個APP裏面是可以有多個activity的,每個activity都是一個展示界面,展現不同視圖),這個時候你當前的activity就進入了stopped狀態,當點擊返回鍵的時候,這個activity又重新啓動。
  • 當用戶使用你的app的時候,接到一個電話,通話結束後,你的app又重新回到前臺

Activity 類提供了這兩個生命週期函數:onStop()onRestart()分別的對應activity暫停和重新啓動的時候的動作,我們可以在這個2個函數來處理我們在activity暫停和重新啓動的時候要做的工作。是完全不可見的,完不像Stopped狀態,是部分遮蓋,可以的,Stopped狀態的時候,處於這個狀態的Acitvity全被覆蓋用戶的焦點完全在另外一個獨立的activity上或者是一個獨立的APP上。

注意:因爲當我們的activity進入到stopped狀態的時候,我們這個activity的實例還是存儲在系統的內存中。那這樣的話,也就允許我們不用自己去實現onStop()和onRestart()(甚至onStart()函數)。對於大多數的activity來說,都是相對簡單的,activity從停止到重新啓動都沒什麼問題,我們要做的也許僅僅是調用onPause來停止那些消耗資源的動作。


圖1:


如圖1所示,當用戶離開你的activity的時候,系統會調用它的onStop函數來停止這個activity,如果用戶返回到處於stopped狀態的activity的時候,系統會調用onRestart()函數,然後僅接着就調用onStart和onResume函數。不管是什麼情況下使得activity進入stopped狀態,系統肯定會在onStop函數之前先調用onPause()函數。

停止的Activity

當你的activity的onStop函數被調用的時候,意味着你的activity將要處於不可見的狀態,當用戶不使用它的時候,這個時候應該釋放絕大部分的資源。一但你的activity進入暫停狀態,那麼,系統可能因爲需要回收內存資源而銷燬你的activity實例。在極端情況下,系統可能直接殺死你的APP的進程,並且不回去調用你的activity的onDestroy回調函數。所以要在onStop中釋放那些可能會引起內存泄露的資源

儘管onPause函數會在onStop之前調用,但是你應該使用onStop函數來執行那些耗時,耗CPU功耗的操作,比方說往數據庫寫數據。

比方說下面的例子,就是實現了onStop來保存未完成的筆記到存儲器。

@Override
protected void onStop() {
    super.onStop();  // Always call the superclass method first

    // Save the note's current draft, because the activity is stopping
    // and we want to be sure the current note progress isn't lost.
    ContentValues values = new ContentValues();
    values.put(NotePad.Notes.COLUMN_NAME_NOTE, getCurrentNoteText());
    values.put(NotePad.Notes.COLUMN_NAME_TITLE, getCurrentNoteTitle());

    getContentResolver().update(
            mUri,    // The URI for the note to update.
            values,  // The map of column names and new values to apply to them.
            null,    // No SELECT criteria are used.
            null     // No WHERE columns are used.
            );
}

當activity暫停的時候,運行在後臺,這個activity的實例會被保存在內存裏, 當我們重新恢復到前臺的時候,系統會調用這個被保存的實例。你不需要再去重新初始化那些在生命週期的Resumed狀態之前的被初始化的數據。而且系統會保存佈局文件裏面每個View的狀態。所以如果用戶在EditText裏面輸入了一些內容,那麼在stopped的時候,它的內容會被自動保存的,我們不需要去存儲它。

注意:即使當系統銷燬了除了stopped狀態的activity,但是這個activity裏面的view對象的狀態還是會被保存下來(比方說一個EditText裏面的文字內容),這個信息會被保存到Bundle(鍵值對的一個容器)裏面,當用戶再次進入這個activity的重新創建的一個實例的時候,可以恢復原來裏面的view對象的狀態,下一節我們會講如何利用Bundle來保存其他的一些數據的狀態,來防止你的你的activity實例被銷燬,重建時候,造成數據損失。

啓動/重新啓動你的Activity

當你的activity從stopped狀態轉到前臺運行,系統會調用它的onRestart函數。系統同樣調用onStart函數,每次你的activity變爲可見的時候,都會調用它(不管你是restart,或者是第一次create這個activity).onRestart函數只有在activity從stopped狀態恢復到前臺運行的時候,纔會調用。所以當activity從stopped狀態恢復,而未被destoryed的情況下,你可以在它裏面實現一些特別的恢復工作。

通常讓APP利用onRestart來恢復activity之前的狀態這種情況是很罕見的,我們幾乎不這麼使用它,所以在一些普通的app上對這個方法的使用沒有任何指導的方法。因爲你onStop函數應該清理你的activity的資源,在restart你的activity的時候,你需要重新去實例化這些資源。當你的activity應用第一次啓動的時候也需要去實例化它們。因爲這個原因,所以很多時候我們使用onStart函數來和onStop函數對應,因爲不管你是第一次創建,還是從stopped狀態restart你的activity,系統都會調用onStart這個函數,而onRestart僅僅在stopped狀態恢復的時候纔會調用。。

比方說用戶長時間離開activity界面,那麼當回到這個界面的時候,onStart函數是一個很好的地方來識別那些需要的系統特性是可以使用的。

@Override
protected void onStart() {
    super.onStart();  // Always call the superclass method first
    
    // The activity is either being restarted or started for the first time
    // so this is where we should make sure that GPS is enabled
    LocationManager locationManager = 
            (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    boolean gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
    
    if (!gpsEnabled) {
        // Create a dialog here that requests the user to enable GPS, and use an intent
        // with the android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS action
        // to take the user to the Settings screen to enable GPS when they click "OK"
    }
}

@Override
protected void onRestart() {
    super.onRestart();  // Always call the superclass method first
    
    // Activity being restarted from stopped state    
}

當系統銷燬你的activity的時候,會調用 onDestroy() 這個函數。因爲我們大部分的釋放系統資源的工作都是在onStop裏面進行的,所以在onDestroy裏面就不需要做很多事情。onDestroy是你最後的機會來清理那些可能會引起內存的泄露的資源,所以你要確保那些額外的線程都被銷燬,其他一些長時間運行的工作也被終止。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章