1. 程式人生 > >3.3 停止和重啟 Activity

3.3 停止和重啟 Activity

線程 intent draft .cn 時間 導航 另一個 googl 進程

正確停止和重啟 Activity 是 Activity 生命周期中的重要過程,其可確保您的用戶知曉應用始終保持活躍狀態並且不會丟失進度。Activity 停止和重啟的場景主要有以下幾種:

  • 用戶打開“最近應用”窗口並從您的應用切換到另一個應用。您的應用中當前位於前臺的 Activity 將停止。 如果用戶從主屏幕啟動器圖標或“最近應用”窗口返回到您的應用,將會重啟 Activity。
  • 用戶在您的應用中執行開始新 Activity 的操作。當第二個 Activity 創建好後,當前 Activity 便停止。 如果用戶之後按了返回按鈕,第一個 Activity 會重新開始。
  • 用戶在其手機上使用您的應用的同時接聽來電。

Activity 類提供兩種生命周期方法: onStop()onRestart(),這些方法允許您專門處理 Activity 句柄停止和重新啟動的方式。 不同於識別部分 UI 阻擋的暫停狀態,停止狀態保證 UI 不再可見,且用戶的焦點在另外的 Activity(或完全獨立的應用)中。

:因為系統在 Activity 停止時會將您的 Activity 實例保留在系統內存中,您根本無需實現 onStop()onRestart() 或甚至onStart() 方法。對於大多數相對簡單的 Activity 而言,Activity 將停止並重新啟動,並且您可能只需使用 onPause()

暫停正在進行的操作,並從系統資源斷開連接。

技術分享

圖 1. 用戶離開 Activity 時,系統會調用 onStop() 停止 Activity (1)。如果用戶在 Activity 停止時返回,系統會調用 onRestart() (2),緊接著調用 onStart() (3) 和 onResume() (4)。請註意,無論什麽場景導致 Activity 停止,系統始終會在調用 onStop() 之前調用 onPause()

停止 Activity

當您的 Activity 收到 onStop() 方法的調用時,它不再可見,並且應釋放幾乎所有用戶不使用時不需要的資源。 一旦您的 Activity 停止,如果需要恢復系統內存,系統可能會銷毀該實例。 在極端情況下,系統可能會僅終止應用進程,而不會調用 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 對象將駐留在內存中並在 Activity 繼續時被再次調用。 您無需重新初始化在任何導致進入“繼續”狀態的回調方法過程中創建的組件。 系統還會在布局中跟蹤每個 View 的當前狀態,如果用戶在 EditText 小部件中輸入文本,該內容會保留,因此您無需保存即可恢復它。

:即使系統在 Activity 停止時銷毀了 Activity,它仍會保留 Bundle(鍵值對的二進制大對象)中的 View 對象(比如 EditText 中的文本),並在用戶導航回 Activity 的相同實例時恢復它們(下一堂課講述更多有關在您的 Activity 被銷毀且重新創建的情況下使用 Bundle 保存其他數據狀態的知識)。

啟動/重啟 Activity

當您的 Activity 從停止狀態返回前臺時,它會接收對 onRestart() 的調用。系統還會在每次您的 Activity 變為可見時調用 onStart() 方法(無論是正重新開始還是初次創建)。但是,只會在 Activity 從停止狀態繼續時調用 onRestart() 方法,因此您可以使用它執行只有在 Activity 之前停止但未銷毀的情況下可能必須執行的特殊恢復工作。

應用需要使用 onRestart() 恢復 Activity 狀態的情況並不常見,因此沒有適用於一般應用群體的任何方法指導原則。 但是,因為您的 onStop() 方法應基本清理所有 Activity 的資源,您將需要在 Activity 重新開始時重新實例化它們。 但是,您還需要在您的 Activity 初次創建時重新實例化它們(沒有 Activity 的現有實例)。 出於此原因,您應經常使用 onStart() 回調方法作為 onStop() 方法的對應部分,因為系統會在它創建您的 Activity 以及從停止狀態重新啟動 Activity 時調用 onStart()

例如,因為用戶可能在回到它之前已離開應用很長時間,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 時,它會調用您的 ActivityonDestroy() 方法。因為您通常應已使用 onStop() 釋放大多數您的資源,到您接收對 onDestroy() 的調用時,大多數應用無需做太多操作。此方法是您清理可導致內存泄露的資源的最後一種方法,因此您應確保其他線程被銷毀且其他長期運行的操作(比如方法跟蹤)也會停止。

3.3 停止和重啟 Activity