Android之Activity系列總結(一)--Activity概述
本文內容
- 建立 Activity
- 實現使用者介面
- 在清單檔案中宣告 Activity
- 啟動 Activity
- 啟動 Activity 以獲得結果
- 結束 Activity
- 管理 Activity 生命週期
- 實現生命週期回撥
- 儲存 Activity 狀態
- 處理配置變更
- 協調 Activity
是一個應用元件,使用者可與其提供的螢幕進行互動,以執行撥打電話、拍攝照片、傳送電子郵件或檢視地圖等操作。 每個 Activity 都會獲得一個用於繪製其使用者介面的視窗。視窗通常會充滿螢幕,但也可小於螢幕並浮動在其他視窗之上。
一個應用通常由多個彼此鬆散聯絡的 Activity 組成。 一般會指定應用中的某個 Activity 為“主”Activity,即首次啟動應用時呈現給使用者的那個 Activity。 而且每個 Activity 均可啟動另一個 Activity,以便執行不同的操作。 每次新 Activity 啟動時,前一 Activity 便會停止,但系統會在堆疊(“返回棧”)中保留該 Activity。 當新 Activity 啟動時,系統會將其推送到返回棧上,並取得使用者焦點。 返回棧遵循基本的“後進先出”堆疊機制,因此,當用戶完成當前 Activity 並按“返回”按鈕時,系統會從堆疊中將其彈出(並銷燬),然後恢復前一 Activity。 (
當一個 Activity 因某個新 Activity 啟動而停止時,系統會通過該 Activity 的生命週期回撥方法通知其這一狀態變化。Activity 因狀態變化—系統是建立 Activity、停止 Activity、恢復 Activity 還是銷燬 Activity— 而收到的回撥方法可能有若干種,每一種回撥都會為您提供執行與該狀態變化相應的特定操作的機會。 例如,停止時,您的 Activity 應釋放任何大型物件,例如網路或資料庫連線。 當 Activity 恢復時,您可以重新獲取所需資源,並恢復執行中斷的操作。 這些狀態轉變都是 Activity 生命週期的一部分。
本文的其餘部分闡述有關如何建立和使用 Activity 的基礎知識(包括對 Activity 生命週期工作方式的全面闡述),以便您正確管理各種 Activity 狀態之間的轉變。
建立 Activity
要建立 Activity,您必須建立 的子類(或使用其現有子類)。您需要在子類中實現 Activity 在其生命週期的各種狀態之間轉變時(例如建立 Activity、停止 Activity、恢復 Activity 或銷燬 Activity 時)系統呼叫的回撥方法。 兩個最重要的回撥方法是:
- 您必須實現此方法。系統會在建立您的 Activity 時呼叫此方法。您應該在實現內初始化 Activity 的必需元件。 最重要的是,您必須在此方法內呼叫,以定義 Activity 使用者介面的佈局。
- 系統將此方法作為使用者離開 Activity 的第一個訊號(但並不總是意味著 Activity 會被銷燬)進行呼叫。 您通常應該在此方法內確認在當前使用者會話結束後仍然有效的任何更改(因為使用者可能不會返回)。
您還應使用幾種其他生命週期回撥方法,以便提供流暢的 Activity 間使用者體驗,以及處理導致您的 Activity 停止甚至被銷燬的意外中斷。 後文的管理 Activity 生命週期部分對所有生命週期回撥方法進行了闡述。
實現使用者介面
Activity 的使用者介面是由層級式檢視 — 衍生自 View
類的物件 — 提供的。每個檢視都控制 Activity 視窗內的特定矩形空間,可對使用者互動作出響應。 例如,檢視可以是在使用者觸控時啟動某項操作的按鈕。
您可以利用 Android 提供的許多現成檢視設計和組織您的佈局。“小部件”是提供按鈕、文字欄位、複選框或僅僅是一幅影象等螢幕視覺(互動式)元素的檢視。 “佈局”是衍生自 的檢視,為其子檢視提供唯一佈局模型,例如線性佈局、網格佈局或相對佈局。 您還可以為 View
類和 類建立子類(或使用其現有子類)來自行建立小部件和佈局,然後將它們應用於您的 Activity 佈局。
利用檢視定義佈局的最常見方法是藉助儲存在您的應用資源內的 XML 佈局檔案。這樣一來,您就可以將使用者介面的設計與定義 Activity 行為的原始碼分開維護。 您可以通過 將佈局設定為 Activity 的 UI,從而傳遞佈局的資源 ID。不過,您也可以在 Activity 程式碼中建立新 View
,並通過將新 View
插入 來建立檢視層次,然後通過將根 傳遞到 來使用該佈局。
如需瞭解有關建立使用者介面的資訊,請參閱使用者介面文件。
在清單檔案中宣告 Activity
您必須在清單檔案中宣告您的 Activity,這樣系統才能訪問它。 要宣告您的 Activity,請開啟您的清單檔案,並將 <activity>
元素新增為 <application>
元素的子項。例如:
1234567 | < 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 過濾器的內容如下所示:
123456 | < 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
您可以通過呼叫 ,並將其傳遞給描述您想啟動的 Activity 的 來啟動另一個 Activity。Intent 物件會指定您想啟動的具體 Activity 或描述您想執行的操作型別(系統會為您選擇合適的 Activity,甚至是來自其他應用的 Activity)。 Intent 物件還可能攜帶少量供所啟動 Activity 使用的資料。
在您的自有應用內工作時,您經常只需要啟動某個已知 Activity。 您可以通過使用類名建立一個顯式定義您想啟動的 Activity 的 Intent 物件來實現此目的。 例如,可以通過以下程式碼讓一個 Activity 啟動另一個名為 SignInActivity
的 Activity:
12 | Intent intent = new Intent( this , SignInActivity. class ); startActivity(intent); |
不過,您的應用可能還需要利用您的 Activity 資料執行某項操作,例如傳送電子郵件、簡訊或狀態更新。 在這種情況下,您的應用自身可能不具有執行此類操作所需的 Activity,因此您可以改為利用裝置上其他應用提供的 Activity 為您執行這些操作。 這便是 Intent 物件的真正價值所在 — 您可以建立一個 Intent 物件,對您想執行的操作進行描述,系統會從其他應用啟動相應的 Activity。 如果有多個 Activity 可以處理 Intent,則使用者可以選擇要使用哪一個。 例如,如果您想允許使用者傳送電子郵件,可以建立以下 Intent:
123 | Intent intent = new Intent(Intent.ACTION_SEND); intent.putExtra(Intent.EXTRA_EMAIL, recipientArray); startActivity(intent); |
新增到 Intent 中的 extra 是一個字串陣列,其中包含應將電子郵件傳送到的電子郵件地址。 當電子郵件應用響應此 Intent 時,它會讀取 extra 中提供的字串陣列,並將它們放入電子郵件撰寫窗體的“收件人”欄位。 在這種情況下,電子郵件應用的 Activity 啟動,並且當用戶完成操作時,您的 Activity 會恢復執行。
啟動 Activity 以獲得結果
例如,您可能希望使用者選取其中一位聯絡人,以便您的 Activity 對該聯絡人中的資訊執行某項操作。 您可以通過以下程式碼建立此類 Intent 並處理結果:
1234567891011121314151617181920 | 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(),
|