Android之Activity系列總結(一)--Activity概覽

Activity

本文內容

  1. 建立 Activity
    1. 實現用戶界面
    2. 在清單文件中聲明 Activity
  2. 啓動 Activity
    1. 啓動 Activity 以得到結果
  3. 結束 Activity
  4. 管理 Activity 生命週期
    1. 實現生命週期回調
    2. 保存 Activity 狀態
    3. 處理配置變動
    4. 協調 Activity

Activity 是一個應用組件,用戶可與其提供的屏幕進行交互,以執行撥打電話、拍攝照片、發送電子郵件或查看地圖等操做。 每一個 Activity 都會得到一個用於繪製其用戶界面的窗口。窗口一般會充滿屏幕,但也可小於屏幕並浮動在其餘窗口之上。html

一個應用一般由多個彼此鬆散聯繫的 Activity 組成。 通常會指定應用中的某個 Activity 爲「主」Activity,即首次啓動應用時呈現給用戶的那個 Activity。 並且每一個 Activity 都可啓動另外一個 Activity,以便執行不一樣的操做。 每次新 Activity 啓動時,前一 Activity 便會中止,但系統會在堆棧(「返回棧」)中保留該 Activity。 當新 Activity 啓動時,系統會將其推送到返回棧上,並取得用戶焦點。 返回棧遵循基本的「後進先出」堆棧機制,所以,當用戶完成當前 Activity 並按「返回」按鈕時,系統會從堆棧中將其彈出(並銷燬),而後恢復前一 Activity。 (任務和返回棧文檔中對返回棧有更詳細的闡述。)java

當一個 Activity 因某個新 Activity 啓動而中止時,系統會經過該 Activity 的生命週期回調方法通知其這一狀態變化。Activity 因狀態變化—系統是建立 Activity、中止 Activity、恢復 Activity 仍是銷燬 Activity— 而收到的回調方法可能有若干種,每一種回調都會爲您提供執行與該狀態變化相應的特定操做的機會。 例如,中止時,您的 Activity 應釋聽任何大型對象,例如網絡或數據庫鏈接。 當 Activity 恢復時,您能夠從新獲取所需資源,並恢復執行中斷的操做。 這些狀態轉變都是 Activity 生命週期的一部分。android

本文的其他部分闡述有關如何建立和使用 Activity 的基礎知識(包括對 Activity 生命週期工做方式的全面闡述),以便您正確管理各類 Activity 狀態之間的轉變。數據庫

建立 Activity


要建立 Activity,您必須建立 Activity 的子類(或使用其現有子類)。您須要在子類中實現 Activity 在其生命週期的各類狀態之間轉變時(例如建立 Activity、中止 Activity、恢復 Activity 或銷燬 Activity 時)系統調用的回調方法。 兩個最重要的回調方法是:數組

onCreate()
您必須實現此方法。系統會在建立您的 Activity 時調用此方法。您應該在實現內初始化 Activity 的必需組件。 最重要的是,您必須在此方法內調用 setContentView(),以定義 Activity 用戶界面的佈局。
onPause()
系統將此方法做爲用戶離開 Activity 的第一個信號(但並不老是意味着 Activity 會被銷燬)進行調用。 您一般應該在此方法內確認在當前用戶會話結束後仍然有效的任何更改(由於用戶可能不會返回)。

您還應使用幾種其餘生命週期回調方法,以便提供流暢的 Activity 間用戶體驗,以及處理致使您的 Activity 中止甚至被銷燬的意外中斷。 後文的管理 Activity 生命週期部分對全部生命週期回調方法進行了闡述。網絡

實現用戶界面

Activity 的用戶界面是由層級式視圖 — 衍生自 View 類的對象 — 提供的。每一個視圖都控制 Activity 窗口內的特定矩形空間,可對用戶交互做出響應。 例如,視圖能夠是在用戶觸摸時啓動某項操做的按鈕。app

您能夠利用 Android 提供的許多現成視圖設計和組織您的佈局。「小部件」是提供按鈕、文本字段、複選框或僅僅是一幅圖像等屏幕視覺(交互式)元素的視圖。 「佈局」是衍生自 ViewGroup 的視圖,爲其子視圖提供惟一佈局模型,例如線性佈局、網格佈局或相對佈局。 您還能夠爲 View 類和 ViewGroup 類建立子類(或使用其現有子類)來自行建立小部件和佈局,而後將它們應用於您的 Activity 佈局。框架

利用視圖定義佈局的最多見方法是藉助保存在您的應用資源內的 XML 佈局文件。這樣一來,您就能夠將用戶界面的設計與定義 Activity 行爲的源代碼分開維護。 您能夠經過 setContentView() 將佈局設置爲 Activity 的 UI,從而傳遞佈局的資源 ID。不過,您也能夠在 Activity 代碼中建立新 View,並經過將新 View 插入 ViewGroup 來建立視圖層次,而後經過將根 ViewGroup 傳遞到 setContentView() 來使用該佈局。ide

如需瞭解有關建立用戶界面的信息,請參閱用戶界面文檔。工具

在清單文件中聲明 Activity

您必須在清單文件中聲明您的 Activity,這樣系統才能訪問它。 要聲明您的 Activity,請打開您的清單文件,並將 <activity> 元素添加爲 <application>元素的子項。例如:

<manifest ... >
  <application ... >
      <activity android:name=".ExampleActivity" />
      ...
  </application ... >
  ...
</manifest >

您還能夠在此元素中加入幾個其餘特性,以定義 Activity 標籤、Activity 圖標或風格主題等用於設置 Activity UI 風格的屬性。 android:name 屬性是惟一必需的屬性—它指定 Activity 的類名。應用一旦發佈,即不該更改此類名,不然,可能會破壞諸如應用快捷方式等一些功能(請閱讀博客文章 Things That Cannot Change [不能更改的內容])。

請參閱 <activity> 元素參考文檔,瞭解有關在清單文件中聲明 Activity 的詳細信息。

使用 Intent 過濾器

<activity> 元素還可指定各類 Intent 過濾器—使用 <intent-filter> 元素—以聲明其餘應用組件激活它的方法。

當您使用 Android SDK 工具建立新應用時,系統自動爲您建立的存根 Activity 包含一個 Intent 過濾器,其中聲明瞭該 Activity 響應「主」操做且應置於「launcher」類別內。 Intent 過濾器的內容以下所示:

<activity android:name=".ExampleActivity" android:icon="@drawable/app_icon">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

<action> 元素指定這是應用的「主」入口點。<category> 元素指定此 Activity 應列入系統的應用啓動器內(以便用戶啓動該 Activity)。

若是您打算讓應用成爲獨立應用,不容許其餘應用激活其 Activity,則您不須要任何其餘 Intent 過濾器。 正如前例所示,只應有一個 Activity 具備「主」操做和「launcher」類別。 您不想提供給其餘應用的 Activity 不該有任何 Intent 過濾器,您能夠利用顯式 Intent 自行啓動它們(下文對此作了闡述)。

不過,若是您想讓 Activity 對衍生自其餘應用(以及您的自有應用)的隱式 Intent 做出響應,則必須爲 Activity 定義其餘 Intent 過濾器。 對於您想要做出響應的每個 Intent 類型,您都必須加入相應的 <intent-filter>,其中包括一個 <action> 元素,還可選擇性地包括一個 <category> 元素和/或一個<data> 元素。這些元素指定您的 Activity 能夠響應的 Intent 類型。

如需瞭解有關您的 Activity 如何響應 Intent 的詳細信息,請參閱 Intent 和 Intent 過濾器文檔。

啓動 Activity


您能夠經過調用 startActivity(),並將其傳遞給描述您想啓動的 Activity 的 Intent 來啓動另外一個 Activity。Intent 對象會指定您想啓動的具體 Activity 或描述您想執行的操做類型(系統會爲您選擇合適的 Activity,甚至是來自其餘應用的 Activity)。 Intent 對象還可能攜帶少許供所啓動 Activity 使用的數據。

在您的自有應用內工做時,您常常只須要啓動某個已知 Activity。 您能夠經過使用類名建立一個顯式定義您想啓動的 Activity 的 Intent 對象來實現此目的。 例如,能夠經過如下代碼讓一個 Activity 啓動另外一個名爲 SignInActivity 的 Activity:

Intent intent = new Intent(this, SignInActivity.class);
startActivity(intent);

不過,您的應用可能還須要利用您的 Activity 數據執行某項操做,例如發送電子郵件、短信或狀態更新。 在這種狀況下,您的應用自身可能不具備執行此類操做所需的 Activity,所以您能夠改成利用設備上其餘應用提供的 Activity 爲您執行這些操做。 這即是 Intent 對象的真正價值所在 — 您能夠建立一個 Intent 對象,對您想執行的操做進行描述,系統會從其餘應用啓動相應的 Activity。 若是有多個 Activity 能夠處理 Intent,則用戶能夠選擇要使用哪個。 例如,若是您想容許用戶發送電子郵件,能夠建立如下 Intent:

Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_EMAIL, recipientArray);
startActivity(intent);

添加到 Intent 中的 EXTRA_EMAIL extra 是一個字符串數組,其中包含應將電子郵件發送到的電子郵件地址。 當電子郵件應用響應此 Intent 時,它會讀取 extra 中提供的字符串數組,並將它們放入電子郵件撰寫窗體的「收件人」字段。 在這種狀況下,電子郵件應用的 Activity 啓動,而且當用戶完成操做時,您的 Activity 會恢復執行。

啓動 Activity 以得到結果

有時,您可能須要從啓動的 Activity 得到結果。在這種狀況下,請經過調用 startActivityForResult()(而非 startActivity())來啓動 Activity。 要想在隨後收到後續 Activity 的結果,請實現 onActivityResult() 回調方法。 當後續 Activity 完成時,它會使用 Intent 向您的 onActivityResult() 方法返回結果。

例如,您可能但願用戶選取其中一位聯繫人,以便您的 Activity 對該聯繫人中的信息執行某項操做。 您能夠經過如下代碼建立此類 Intent 並處理結果:

private void pickContact() {
    // Create an intent to "pick" a contact, as defined by the content provider URI
    Intent intent = new Intent(Intent.ACTION_PICK, Contacts.CONTENT_URI);
    startActivityForResult(intent, PICK_CONTACT_REQUEST);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // If the request went well (OK) and the request was PICK_CONTACT_REQUEST
    if (resultCode == Activity.RESULT_OK && requestCode == PICK_CONTACT_REQUEST) {
        // Perform a query to the contact's content provider for the contact's name
        Cursor cursor = getContentResolver().query(data.getData(),
        new String[] {Contacts.DISPLAY_NAME}, null, null, null);
        if (cursor.moveToFirst()) { // True if the cursor is not empty
            int columnIndex = cursor.getColumnIndex(Contacts.DISPLAY_NAME);
            String name = cursor.getString(columnIndex);
            // Do something with the selected contact's name...
        }
    }
}

上例顯示的是,您在處理 Activity 結果時應該在 onActivityResult() 方法中使用的基本邏輯。 第一個條件檢查請求是否成功(若是成功,則resultCode將爲 RESULT_OK)以及此結果響應的請求是否已知 — 在此狀況下,requestCode與隨 startActivityForResult() 發送的第二個參數匹配。 代碼經過查詢Intent 中返回的數據(data 參數)從該處開始處理 Activity 結果。

實際狀況是,ContentResolver 對一個內容提供程序執行查詢,後者返回一個 Cursor,讓查詢的數據可以被讀取。如需瞭解詳細信息,請參閱內容提供程序文檔。

如需瞭解有關 Intent 用法的詳細信息,請參閱 Intent 和 Intent 過濾器文檔。

結束 Activity


您能夠經過調用 Activity 的 finish() 方法來結束該 Activity。您還能夠經過調用 finishActivity() 結束您以前啓動的另外一個 Activity。

:在大多數狀況下,您不該使用這些方法顯式結束 Activity。 正以下文有關 Activity 生命週期的部分所述,Android 系統會爲您管理 Activity 的生命週期,所以您無需結束本身的 Activity。 調用這些方法可能對預期的用戶體驗產生不良影響,所以只應在您確實不想讓用戶返回此 Activity 實例時使用。

管理 Activity 生命週期


經過實現回調方法管理 Activity 的生命週期對開發強大而又靈活的應用相當重要。 Activity 的生命週期會直接受到 Activity 與其餘 Activity、其任務及返回棧的關聯性的影響。

Activity 基本上以三種狀態存在:

繼續
此 Activity 位於屏幕前臺並具備用戶焦點。(有時也將此狀態稱做「運行中」。)
暫停
另外一個 Activity 位於屏幕前臺並具備用戶焦點,但此 Activity 仍可見。也就是說,另外一個 Activity 顯示在此 Activity 上方,而且該 Activity 部分透明或未覆蓋整個屏幕。 暫停的 Activity 處於徹底活動狀態( Activity 對象保留在內存中,它保留了全部狀態和成員信息,並與窗口管理器保持鏈接),但在內存極度不足的狀況下,可能會被系統終止。
中止
該 Activity 被另外一個 Activity 徹底遮蓋(該 Activity 目前位於「後臺」)。 已中止的 Activity 一樣仍處於活動狀態( Activity 對象保留在內存中,它保留了全部狀態和成員信息,但 與窗口管理器鏈接)。 不過,它對用戶再也不可見,在他處須要內存時可能會被系統終止。

若是 Activity 處於暫停或中止狀態,系統可經過要求其結束(調用其 finish() 方法)或直接終止其進程,將其從內存中刪除。(將其結束或終止後)再次打開 Activity 時,必須重建。

實現生命週期回調

當一個 Activity 轉入和轉出上述不一樣狀態時,系統會經過各類回調方法向其發出通知。 全部回調方法都是掛鉤,您能夠在 Activity 狀態發生變化時替代這些掛鉤來執行相應操做。 如下框架 Activity 包括每個基本生命週期方法:

public class ExampleActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // The activity is being created.
    }
    @Override
    protected void onStart() {
        super.onStart();
        // The activity is about to become visible.
    }
    @Override
    protected void onResume() {
        super.onResume();
        // The activity has become visible (it is now "resumed").
    }
    @Override
    protected void onPause() {
        super.onPause();
        // Another activity is taking focus (this activity is about to be "paused").
    }
    @Override
    protected void onStop() {
        super.onStop();
        // The activity is no longer visible (it is now "stopped")
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        // The activity is about to be destroyed.
    }
}

  

:正如以上示例所示,您在實現這些生命週期方法時必須始終先調用超類實現,而後再執行任何操做。

這些方法共同定義 Activity 的整個生命週期。您能夠經過實現這些方法監控 Activity 生命週期中的三個嵌套循環:

  • Activity 的整個生命週期發生在 onCreate() 調用與 onDestroy() 調用之間。您的 Activity 應在 onCreate() 中執行「全局」狀態設置(例如定義佈局),並釋放 onDestroy() 中的全部其他資源。例如,若是您的 Activity 有一個在後臺運行的線程,用於從網絡上下載數據,它可能會在 onCreate() 中建立該線程,而後在 onDestroy() 中中止該線程。
  • Activity 的可見生命週期發生在 onStart() 調用與 onStop() 調用之間。在這段時間,用戶能夠在屏幕上看到 Activity 並與其交互。 例如,當一個新 Activity 啓動,而且此 Activity 再也不可見時,系統會調用 onStop()。您能夠在調用這兩個方法之間保留向用戶顯示 Activity 所需的資源。 例如,您能夠在 onStart() 中註冊一個 BroadcastReceiver 以監控影響 UI 的變化,並在用戶沒法再看到您顯示的內容時在 onStop() 中將其取消註冊。在 Activity 的整個生命週期,當 Activity 在對用戶可見和隱藏兩種狀態中交替變化時,系統可能會屢次調用 onStart() 和 onStop()

  • Activity 的前臺生命週期發生在 onResume() 調用與 onPause() 調用之間。在這段時間,Activity 位於屏幕上的全部其餘 Activity 以前,並具備用戶輸入焦點。 Activity 可頻繁轉入和轉出前臺 — 例如,當設備轉入休眠狀態或出現對話框時,系統會調用 onPause()。 因爲此狀態可能常常發生轉變,所以這兩個方法中應採用適度輕量級的代碼,以免因轉變速度慢而讓用戶等待。

圖 1 說明了這些循環以及 Activity 在狀態轉變期間可能通過的路徑。矩形表示回調方法,當 Activity 在不一樣狀態之間轉變時,您能夠實現這些方法來執行操做。

圖 1. Activity 生命週期。

表 1 列出了相同的生命週期回調方法,其中對每一種回調方法作了更詳細的描述,並說明了每一種方法在 Activity 整個生命週期內的位置,包括在回調方法完成後系統可否終止 Activity。

表 1. Activity 生命週期回調方法彙總表。

方法 說明 是否能過後終止? 後接
onCreate() 首次建立 Activity 時調用。 您應該在此方法中執行全部正常的靜態設置 — 建立視圖、將數據綁定到列表等等。 系統向此方法傳遞一個 Bundle 對象,其中包含 Activity 的上一狀態,不過前提是捕獲了該狀態(請參閱後文的保存 Activity 狀態)。

始終後接 onStart()

onStart()
     onRestart() 在 Activity 已中止並即將再次啓動前調用。

始終後接 onStart()

onStart()
onStart() 在 Activity 即將對用戶可見以前調用。

若是 Activity 轉入前臺,則後接 onResume(),若是 Activity 轉入隱藏狀態,則後接 onStop()

onResume() 

onStop()
     onResume() 在 Activity 即將開始與用戶進行交互以前調用。 此時,Activity 處於 Activity 堆棧的頂層,並具備用戶輸入焦點。

始終後接 onPause()

onPause()
onPause() 當系統即將開始繼續另外一個 Activity 時調用。 此方法一般用於確認對持久性數據的未保存更改、中止動畫以及其餘可能消耗 CPU 的內容,諸如此類。 它應該很是迅速地執行所需操做,由於它返回後,下一個 Activity 才能繼續執行。

若是 Activity 返回前臺,則後接 onResume(),若是 Activity 轉入對用戶不可見狀態,則後接onStop()

onResume() 

onStop()
onStop() 在 Activity 對用戶再也不可見時調用。若是 Activity 被銷燬,或另外一個 Activity(一個現有 Activity 或新 Activity)繼續執行並將其覆蓋,就可能發生這種狀況。

若是 Activity 恢復與用戶的交互,則後接 onRestart(),若是 Activity 被銷燬,則後接onDestroy()

onRestart()

onDestroy()
onDestroy() 在 Activity 被銷燬前調用。這是 Activity 將收到的最後調用。 當 Activity 結束(有人對 Activity 調用了 finish()),或系統爲節省空間而暫時銷燬該 Activity 實例時,可能會調用它。 您能夠經過 isFinishing() 方法區分這兩種情形。

名爲「是否能過後終止?」的列表示系統是否能在不執行另外一行 Activity 代碼的狀況下,在方法返回後隨時終止承載 Activity 的進程。 有三個方法帶

有「是」標記:(onPause()onStop() 和 onDestroy())。因爲 onPause() 是這三個方法中的第一個,所以 Activity 建立後,onPause() 一定成爲最後調用的方法,而後才能終止進程 — 若是系統在緊急狀況下必須恢復內存,則可能不會調用 onStop() 和 onDestroy()。所以,您應該使用 onPause() 向存儲設備寫入相當重要的持久性數據(例如用戶編輯)。不過,您應該對 onPause() 調用期間必須保留的信息有所選擇,由於該方法中的任何阻止過程都會妨礙向下一個 Activity 的轉變並拖慢用戶體驗。

是否能在過後終止?列中標記爲「否」的方法可從系統調用它們的一刻起防止承載 Activity 的進程被終止。 所以,在從 onPause() 返回的時間到onResume() 被調用的時間,系統能夠終止 Activity。在 onPause() 被再次調用並返回前,將沒法再次終止 Activity。

:根據表 1 中的定義屬於技術上沒法「終止」的 Activity 仍可能被系統終止 — 但這種狀況只有在無任何其餘資源的極端狀況下才會發生。進程和線程處理文檔對可能會終止 Activity 的狀況作了更詳盡的闡述。

保存 Activity 狀態

管理 Activity 生命週期的引言部分簡要說起,當 Activity 暫停或中止時,Activity 的狀態會獲得保留。 確實如此,由於當 Activity 暫停或中止時,Activity 對象仍保留在內存中 — 有關其成員和當前狀態的全部信息仍處於活動狀態。 所以,用戶在 Activity 內所作的任何更改都會獲得保留,這樣一來,當 Activity 返回前臺(當它「繼續」)時,這些更改仍然存在。

不過,當系統爲了恢復內存而銷燬某項 Activity 時,Activity 對象也會被銷燬,所以系統在繼續 Activity 時根本沒法讓其狀態保持無缺,而是必須在用戶返回 Activity 時重建 Activity 對象。但用戶並不知道系統銷燬 Activity 後又對其進行了重建,所以他們極可能認爲 Activity 狀態毫無變化。 在這種狀況下,您能夠實現另外一個回調方法對有關 Activity 狀態的信息進行保存,以確保有關 Activity 狀態的重要信息獲得保留:onSaveInstanceState()

系統會先調用 onSaveInstanceState(),而後再使 Activity 變得易於銷燬。系統會向該方法傳遞一個 Bundle,您能夠在其中使用 putString() 和putInt() 等方法以名稱-值對形式保存有關 Activity 狀態的信息。而後,若是系統終止您的應用進程,而且用戶返回您的 Activity,則系統會重建該 Activity,並將 Bundle 同時傳遞給 onCreate() 和 onRestoreInstanceState()。您可使用上述任一方法從 Bundle 提取您保存的狀態並恢復該 Activity 狀態。若是沒有狀態信息須要恢復,則傳遞給您的 Bundle 是空值(若是是首次建立該 Activity,就會出現這種狀況)。

圖 2. 在兩種狀況下,Activity 重獲用戶焦點時可保持狀態無缺:系統在銷燬 Activity 後重建 Activity,Activity 必須恢復以前保存的狀態;系統中止 Activity 後繼續執行 Activity,而且 Activity 狀態保持無缺。

:沒法保證系統會在銷燬您的 Activity 前調用 onSaveInstanceState(),由於存在不須要保存狀態的狀況(例如用戶使用「返回」按鈕離開您的 Activity 時,由於用戶的行爲是在顯式關閉 Activity)。 若是系統調用 onSaveInstanceState(),它會在調用 onStop() 以前,而且可能會在調用onPause() 以前進行調用。

不過,即便您什麼都不作,也不實現 onSaveInstanceState()Activity 類的 onSaveInstanceState() 默認實現也會恢復部分 Activity 狀態。具體地講,默認實現會爲佈局中的每一個 View 調用相應的 onSaveInstanceState() 方法,讓每一個視圖都能提供有關自身的應保存信息。Android 框架中幾乎每一個小部件都會根據須要實現此方法,以便在重建 Activity 時自動保存和恢復對 UI 所作的任何可見更改。例如,EditText 小部件保存用戶輸入的任何文本,CheckBox 小部件保存複選框的選中或未選中狀態。您只需爲想要保存其狀態的每一個小部件提供一個惟一的 ID(經過 android:id 屬性)。若是小部件沒有 ID,則系統沒法保存其狀態。

儘管 onSaveInstanceState() 的默認實現會保存有關您的Activity UI 的有用信息,您可能仍需替換它以保存更多信息。例如,您可能須要保存在 Activity 生命週期內發生了變化的成員值(它們可能與 UI 中恢復的值有關聯,但默認狀況下系統不會恢復儲存這些 UI 值的成員)。

因爲 onSaveInstanceState() 的默認實現有助於保存 UI 的狀態,所以若是您爲了保存更多狀態信息而替換該方法,應始終先調用 onSaveInstanceState() 的超類實現,而後再執行任何操做。 一樣,若是您替換onRestoreInstanceState() 方法,也應調用它的超類實現,以便默認實現可以恢復視圖狀態。

:因爲沒法保證系統會調用 onSaveInstanceState(),所以您只應利用它來記錄 Activity 的瞬態(UI 的狀態)— 切勿使用它來存儲持久性數據,而應使用 onPause() 在用戶離開 Activity 後存儲持久性數據(例如應保存到數據庫的數據)。

您只需旋轉設備,讓屏幕方向發生變化,就能有效地測試您的應用的狀態恢復能力。 當屏幕方向變化時,系統會銷燬並重建 Activity,以便應用可供新屏幕配置使用的備用資源。 單憑這一理由,您的 Activity 在重建時可否徹底恢復其狀態就顯得很是重要,由於用戶在使用應用時常常須要旋轉屏幕。

處理配置變動

有些設備配置可能會在運行時發生變化(例如屏幕方向、鍵盤可用性及語言)。 發生此類變化時,Android 會重建運行中的 Activity(系統調用onDestroy(),而後當即調用 onCreate())。此行爲旨在經過利用您提供的備用資源(例如適用於不一樣屏幕方向和屏幕尺寸的不一樣佈局)自動從新加載您的應用來幫助它適應新配置。

若是您對 Activity 進行了適當設計,讓它可以按以上所述處理屏幕方向變化帶來的重啓並恢復 Activity 狀態,那麼在遭遇 Activity 生命週期中的其餘意外事件時,您的應用將具備更強的適應性。

正如上文所述,處理此類重啓的最佳方法是利用onSaveInstanceState() 和 onRestoreInstanceState()(或 onCreate())保存並恢復 Activity 的狀態。

如需瞭解有關運行時發生的配置變動以及應對方法的詳細信息,請閱讀處理運行時變動指南。

協調 Activity

當一個 Activity 啓動另外一個 Activity 時,它們都會體驗到生命週期轉變。第一個 Activity 暫停並中止(但若是它在後臺仍然可見,則不會中止)時,同時系統會建立另外一個 Activity。 若是這些 Activity 共用保存到磁盤或其餘地方的數據,必須瞭解的是,在建立第二個 Activity 前,第一個 Activity 不會徹底中止。更確切地說,啓動第二個 Activity 的過程與中止第一個 Activity 的過程存在重疊。

生命週期回調的順序通過明肯定義,當兩個 Activity 位於同一進程,而且由一個 Activity 啓動另外一個 Activity 時,其定義尤爲明確。 如下是當 Activity A 啓動 Activity B 時一系列操做的發生順序:

  1. Activity A 的 onPause() 方法執行。
  2. Activity B 的 onCreate()onStart() 和 onResume() 方法依次執行。(Activity B 如今具備用戶焦點。)
  3. 而後,若是 Activity A 在屏幕上再也不可見,則其 onStop() 方法執行。

您能夠利用這種可預測的生命週期回調順序管理從一個 Activity 到另外一個 Activity 的信息轉變。 例如,若是您必須在第一個 Activity 中止時向數據庫寫入數據,以便下一個 Activity 可以讀取該數據,則應在 onPause() 而不是 onStop() 執行期間向數據庫寫入數據。

 

摘自Android官方文檔:https://developer.android.google.cn/guide/components/activities.html

 

Activity系列文章:

Android之Activity系列總結(一)--Activity概覽

Android之Activity系列總結(二)--任務和返回棧

Android 旋轉屏幕--處理Activity與AsyncTask的最佳解決方案(處理運行時變動)

 Activity之概覽屏幕(Overview Screen)

相關文章
相關標籤/搜索