2013年3月17日 星期日

Activity - Android 新手學習筆記

這是一篇封存了一年半多的文章,我也忘了寫完了沒,先PO再說 ^_^

Activity 主要是用來做 UI,或者應該說,是用來放各種 UI 元件的底座,也可以說是一個視窗

一個應用程式可以有多個 Activity,但只會有一個主要入口的 Activity,再由這個 Activity 視需要開啟其他的 Activity

當另一個 Activity 被開啟,則原有的 Activity 就會被 pause 或 stop,並保存在 back stack 中,當前景 Activity 關閉時,再由 back stack 中採後進先出的方法取回最上面的 Activity 會呈現

當前景 Activity 佔滿整個畫面時,背後的 Activity 會觸發 onPause 及 onStop
但若前景 Activity 沒有佔滿整個畫面時,例如是個 Dialog,則背後的 Activity 只會觸發 onPause


下圖是官網的 Lifecycle 圖
(本圖不是全部的事件,只是幾個主要的事件)

兩個重要的事件是 onCreate 及 onPause
在 onCreate 必需呼叫 setContentView() 來呈現 UI
至於 onPause,雖然上面有說當 Activity 關閉時,會由 back stack 取最上面的 Activity 來呈現,但官網又說,我們應該在 onPause 就儲存必要的資料,因為使用者可能不會再回來這個 Activity 實體,例如資源不足時,這個 Activity 就有可能被 kill 掉,目前不知直接回到首頁的功能是否也會有這樣的結果

官網又提到了 onSaveInstanceState() 一般會在 onPause 之前觸發,一般應用程式會依需要來實作此事件,就算沒實作,底層也會自動儲存某些資料,例如有設 id 的輸入元件的值 (沒設 id 的不會存),但也說,這個事件不一定會被觸發,例如使用者用返回鍵或其他方式關掉了這個 Activity,因為此時就不需要保存這些狀態資料

另外,實測時發現,螢幕轉向也會觸發 onCreate() ,其他事件還沒有一一確認

在應用程式中,每個 Activity 都應被註冊在 AndroidManifest.xml,如此才能使用,否則在開啟該 Activity 時會出錯

在 AndroidManifest.xml 中可以設定 Intent filters,Intent filters 是用來定義其他應用程式可以對此 Activity 進行什麼動作

在使用 Eclipse plugin 新增 Android Project 時,會自動產生一個主要入口的 Activity,此 Activity 就會預設有一個 Intent filter,定義了下面兩個設定

        <action android:name="android.intent.action.MAIN"></action>
        <category android:name="android.intent.category.LAUNCHER"></category>

android.intent.action.MAIN 這個 action 表示此 Activity 是這個 Application 的入口
android.intent.category.LAUNCHER 這個 category 表示要將此 Activity 列在使用者的應用程式清單中,以讓使用者點選進入

如果沒有定義其他特定的 Intent filter,那麼其他的應用程式將無法對此 Activity 進行控制
在同一個應用程式中,只能有一個 Activity 定義上面兩個屬性(MAIN action & LAUNCHER category)

啟動其他 Activity 的方法是呼叫 startActivity(Intent intent) 或其他 startActivit... 的 method,在這些 method 的參數中,沒有直接指定要開啟哪一個 Activity (沒有 Activity 型態的參數),因為這是要透過 Intent (意圖) 來指定的,例如

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

在開啟另一個 Activity 時,也可以傳遞一些資料給它,例如

Intent intent = new Intent(this,MySecondActivity.class);
Bundle data = new Bundle();
data.putString("title","My Title");
intent.putExtras(data);
this.startActivity(intent);

上面的 Bundle 就是用來存放我們要傳遞的資料,用法有點像 java.util.Map
而被開啟的 Activity 就可以在 onCreate 用下面的語法來取得傳過來的資料

Intent intent = this.getIntent();
Bundle data = intent.getExtras();
String title = data.getString("title")

1 則留言:

  1. 寫得很清楚! 雖然我很菜還是有點看不懂 哈

    回覆刪除

廣告訊息會被我刪除