本系列開始介紹activity的四大組件,主要是整理網路上關於這一部分的相關資料。包含如下三篇文章:
android基礎知識05:四大組件之activity 01:基礎知識
android基礎知識05:四大組件之activity 02:activity與task
android基礎知識05:四大組件之activity 03:啟動模式執行個體
本文引用了如下文章的資料:
1、詳解 Android 的 Activity 組件
2、關於activity的設計思路和方法 (出處不明)
3、Android Activity LaunchMode 驗證
對activiy的介紹包括幾個方面:
1、activity的狀態
2、activity的生命週期
3、activity之間的通訊
4、Activity 的 Intent Filter
5、activity與task
6、activity的啟動模式執行個體
1、activity的狀態
在 android 中,Activity 擁有四種基本狀態:
1)Active/Runing一個新 Activity 啟動入棧後,它在螢幕最前端,處於棧的最頂端,此時它處於可見並可和使用者互動的啟用狀態。
2)Paused 當 Activity 被另一個透明或者 Dialog 樣式的 Activity 覆蓋時的狀態。此時它依然與視窗管理器保持串連,系統繼續維護其內部狀態,所以它仍然可見,但它已經失去了焦點故不可與使用者互動。
3)Stoped 當 Activity 被另外一個 Activity 覆蓋、失去焦點並不可見時處於 Stoped狀態。
4)Killed Activity 被系統殺死回收或者沒有被啟動時處於 Killed狀態。
當一個 Activity 執行個體被建立、銷毀或者啟動另外一個 Activity 時,它在這四種狀態之間進行轉換,這種轉換的發生依賴於使用者程式的動作。說明了 Activity 在不同狀態間轉換的時機和條件:
如上所示,Android 程式員可以決定一個 Activity 的“生”,但不能決定它的“死”,也就時說程式員可以啟動一個 Activity,但是卻不能手動的“結束”一個 Activity。當你調用 Activity.finish()方法時,結果和使用者按下 BACK 鍵一樣:告訴 Activity Manager 該 Activity 執行個體完成了相應的工作,可以被“回收”。隨後 Activity Manager 啟用處於棧第二層的 Activity 並重新入棧,同時原 Activity 被壓入到棧的第二層,從
Active 狀態轉到 Paused 狀態。例如:從 Activity1 中啟動了 Activity2,則當前處於棧頂端的是 Activity2,第二層是 Activity1,當我們調用 Activity2.finish()方法時,Activity Manager 重新啟用 Activity1 併入棧,Activity2 從 Active 狀態轉換 Stoped 狀態,Activity1. onActivityResult(int requestCode, int resultCode, Intent data)方法被執行,Activity2
返回的資料通過 data參數返回給 Activity1。
2、activity的生命週期
這一部分在本人博文android基礎知識04:組件生命週期(一)有詳細介紹。
3、activity之間的通訊
activity之間的通訊方式包括:使用intent通訊、SharedPreferences、SQLite,檔案等
1)使用intent通訊
在 Android 中,不同的 Activity 執行個體可能運行在一個進程中,也可能運行在不同的進程中。因此我們需要一種特別的機制協助我們在 Activity 之間傳遞訊息。Android 中通過 Intent 對象來表示一條訊息,一個 Intent 對象不僅包含有這個訊息的目的地,還可以包含訊息的內容,這好比一封 Email,其中不僅應該包含收件地址,還可以包含具體的內容。對於一個 Intent 對象,訊息“目的地”是必須的,而內容則是可選項。
在上面的執行個體中通過 Activity. startActivity(intent)啟動另外一個 Activity 的時候,我們在 Intent 類的構造器中指定了“收件者地址”。
如果我們想要給“收件者”Activity 說點什麼的話,那麼可以通過下面這封“e-mail”來將我們訊息傳遞出去
Intent intent =new Intent(CurrentActivity.this,OtherActivity.class); // 建立一個帶“收件者地址”的 email Bundle bundle =new Bundle();// 建立 email 內容 bundle.putBoolean("boolean_key", true);// 編寫內容 bundle.putString("string_key", "string_value"); intent.putExtra("key", bundle);// 封裝 email startActivity(intent);// 啟動新的 Activity
那麼“收件者”該如何收信呢?在 OtherActivity類的 onCreate()或者其它任何地方使用下面的代碼就可以開啟這封“e-mail”閱讀其中的資訊:
Intent intent =getIntent();// 收取 email Bundle bundle =intent.getBundleExtra("key");// 開啟 email bundle.getBoolean("boolean_key");// 讀取內容 bundle.getString("string_key");
上面我們通過 bundle對象來傳遞資訊,bundle維護了一個 HashMap<String, Object>對象,將我們的資料存貯在這個 HashMap 中來進行傳遞。但是像上面這樣的代碼稍顯複雜,因為 Intent 內部為我們準備好了一個 bundle,所以我們也可以使用這種更為簡便的方法:
Intent intent =new Intent(EX06.this,OtherActivity.class); intent.putExtra("boolean_key", true); intent.putExtra("string_key", "string_value"); startActivity(intent);
接收:
Intent intent=getIntent(); intent.getBooleanExtra("boolean_key",false); intent.getStringExtra("string_key");
2)SharedPreferences
SharedPreferences 使用 xml 格式為 Android 應用提供一種永久的資料存貯方式。對於一個 Android 應用,它存貯在檔案系統的 /data/ data/your_app_package_name/shared_prefs/目錄下,可以被處在同一個應用中的所有 Activity 訪問。Android 提供了相關的 API 來處理這些資料而不需要程式員直接操作這些檔案或者考慮資料同步問題。
// 寫入 SharedPreferences SharedPreferences preferences = getSharedPreferences("name", MODE_PRIVATE); Editor editor = preferences.edit(); editor.putBoolean("boolean_key", true); editor.putString("string_key", "string_value"); editor.commit(); // 讀取 SharedPreferences SharedPreferences preferences = getSharedPreferences("name", MODE_PRIVATE); preferences.getBoolean("boolean_key", false); preferences.getString("string_key", "default_value");
3)其他方式
Android 提供了包括 SharedPreferences 在內的很多種資料存貯方式,比如 SQLite,檔案等,程式員可以通過這些 API 實現 Activity 之間的資料交換。如果必要,我們還可以使用 IPC 方式。
4、Activity 的 Intent Filter
Intent Filter 描述了一個組件願意接收什麼樣的 Intent 對象,Android 將其抽象為 android.content.IntentFilter 類。在 Android 的 AndroidManifest.xml 設定檔中可以通過 <intent-filter >節點為一個 Activity 指定其 Intent Filter,以便告訴系統該 Activity 可以響應什麼類型的 Intent。
當程式員使用 startActivity(intent) 來啟動另外一個 Activity 時,如果直接指定 intent 了對象的 Component 屬性,那麼 Activity Manager 將試圖啟動其 Component 屬性指定的 Activity。否則 Android 將通過 Intent 的其它屬性從安裝在系統中的所有 Activity 中尋找與之最匹配的一個啟動,如果沒有找到合適的 Activity,應用程式會得到一個系統拋出的異常。這個匹配的過程如下:
實際上在實際應用中,有時候返回的優先順序最高的intent filter可能有幾個,這時候android會彈出一個對話方塊給使用者選擇(你在使用手機的時候,有沒有注意到,有時候會讓你選擇適合的應用程式,並可以將所選擇的應用程式設定為預設的,比如IME選擇)。
1)action匹配
Action 是一個使用者定義的字串,用於描述一個 Android 應用程式組件,一個 Intent Filter 可以包含多個 Action。在 AndroidManifest.xml 的 Activity 定義時可以在其 <intent-filter >節點指定一個 Action 列表用於標示 Activity 所能接受的“動作”,例如:
<intent-filter > <action android:name="android.intent.action.MAIN" /> <action android:name="com.zy.myaction" /> …… </intent-filter>
如果我們在啟動一個 Activity 時使用這樣的 Intent 對象:
Intent intent =new Intent(); intent.setAction("com.zy.myaction");
那麼所有的 Action 列表中包含了“com.zy.myaction”的 Activity 都將會匹配成功。
Android 預定義了一系列的 Action 分別表示特定的系統動作。這些 Action 通過常量的方式定義在 android.content. Intent中,以“ACTION_”開頭。我們可以在 Android 提供的文檔中找到它們的詳細說明。
2)URI 資料匹配
一個 Intent 可以通過 URI 攜帶外部資料給目標組件。在 <intent-filter >節點中,通過 <data/>節點匹配外部資料。
mimeType 屬性指定攜帶外部資料的資料類型,scheme 指定協議,host、port、path 指定資料的位置、連接埠、和路徑。如下:
<data android:mimeType="mimeType" android:scheme="scheme" android:host="host" android:port="port" android:path="path"/>
如果在 Intent Filter 中指定了這些屬性,那麼只有所有的屬性都匹配成功時 URI 資料匹配才會成功。
3)Category 類別匹配
<intent-filter >節點中可以為組件定義一個 Category 類別列表,當 Intent 中包含這個列表的所有項目時 Category 類別匹配才會成功。
5、activity與task
參看博文
6、activity的啟動模式執行個體